2 * Copyright © 2008 George Sapountzis <gsap7@yahoo.gr>
3 * Copyright © 2008 Red Hat, Inc
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without
7 * fee, provided that the above copyright notice appear in all copies
8 * and that both that copyright notice and this permission notice
9 * appear in supporting documentation, and that the name of the
10 * copyright holders not be used in advertising or publicity
11 * pertaining to distribution of the software without specific,
12 * written prior permission. The copyright holders make no
13 * representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied
17 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
18 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
22 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
27 #ifdef HAVE_DIX_CONFIG_H
28 #include <dix-config.h>
39 #include <GL/internal/dri_interface.h>
40 #include <GL/glxtokens.h>
42 #include "scrnintstr.h"
43 #include "pixmapstr.h"
47 #include "glxserver.h"
49 #include "glxdricommon.h"
51 #include "glapitable.h"
55 #include "extension_string.h"
57 /* RTLD_LOCAL is not defined on Cygwin */
64 typedef struct __GLXDRIscreen __GLXDRIscreen;
65 typedef struct __GLXDRIcontext __GLXDRIcontext;
66 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
68 struct __GLXDRIscreen {
70 __DRIscreen *driScreen;
73 const __DRIcoreExtension *core;
74 const __DRIswrastExtension *swrast;
75 const __DRIcopySubBufferExtension *copySubBuffer;
76 const __DRItexBufferExtension *texBuffer;
77 const __DRIconfig **driConfigs;
80 struct __GLXDRIcontext {
82 __DRIcontext *driContext;
85 struct __GLXDRIdrawable {
87 __DRIdrawable *driDrawable;
88 __GLXDRIscreen *screen;
90 GCPtr gc; /* scratch GC for span drawing */
91 GCPtr swapgc; /* GC for swapping the color buffers */
95 __glXDRIdrawableDestroy(__GLXdrawable * drawable)
97 __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
98 const __DRIcoreExtension *core = private->screen->core;
100 (*core->destroyDrawable) (private->driDrawable);
102 FreeGC(private->gc, (GContext) 0);
103 FreeGC(private->swapgc, (GContext) 0);
105 __glXDrawableRelease(drawable);
111 __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable * drawable)
113 __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
114 const __DRIcoreExtension *core = private->screen->core;
116 (*core->swapBuffers) (private->driDrawable);
122 __glXDRIdrawableCopySubBuffer(__GLXdrawable * basePrivate,
123 int x, int y, int w, int h)
125 __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
126 const __DRIcopySubBufferExtension *copySubBuffer =
127 private->screen->copySubBuffer;
130 (*copySubBuffer->copySubBuffer) (private->driDrawable, x, y, w, h);
134 __glXDRIcontextDestroy(__GLXcontext * baseContext)
136 __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
137 __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
139 (*screen->core->destroyContext) (context->driContext);
140 __glXContextDestroy(&context->base);
145 __glXDRIcontextMakeCurrent(__GLXcontext * baseContext)
147 __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
148 __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
149 __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
150 __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
152 return (*screen->core->bindContext) (context->driContext,
153 draw->driDrawable, read->driDrawable);
157 __glXDRIcontextLoseCurrent(__GLXcontext * baseContext)
159 __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
160 __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
162 return (*screen->core->unbindContext) (context->driContext);
166 __glXDRIcontextCopy(__GLXcontext * baseDst, __GLXcontext * baseSrc,
169 __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
170 __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
171 __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
173 return (*screen->core->copyContext) (dst->driContext,
174 src->driContext, mask);
177 #ifdef __DRI_TEX_BUFFER
180 __glXDRIbindTexImage(__GLXcontext * baseContext,
181 int buffer, __GLXdrawable * glxPixmap)
183 __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
184 const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
185 __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
187 if (texBuffer == NULL)
190 #if __DRI_TEX_BUFFER_VERSION >= 2
191 if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
192 (*texBuffer->setTexBuffer2) (context->driContext,
194 glxPixmap->format, drawable->driDrawable);
198 texBuffer->setTexBuffer(context->driContext,
199 glxPixmap->target, drawable->driDrawable);
205 __glXDRIreleaseTexImage(__GLXcontext * baseContext,
206 int buffer, __GLXdrawable * pixmap)
208 /* FIXME: Just unbind the texture? */
215 __glXDRIbindTexImage(__GLXcontext * baseContext,
216 int buffer, __GLXdrawable * glxPixmap)
222 __glXDRIreleaseTexImage(__GLXcontext * baseContext,
223 int buffer, __GLXdrawable * pixmap)
230 static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
231 __glXDRIbindTexImage,
232 __glXDRIreleaseTexImage
236 __glXDRIscreenDestroy(__GLXscreen * baseScreen)
240 __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
242 (*screen->core->destroyScreen) (screen->driScreen);
244 dlclose(screen->driver);
246 __glXScreenDestroy(baseScreen);
248 if (screen->driConfigs) {
249 for (i = 0; screen->driConfigs[i] != NULL; i++)
250 free((__DRIconfig **) screen->driConfigs[i]);
251 free(screen->driConfigs);
257 static __GLXcontext *
258 __glXDRIscreenCreateContext(__GLXscreen * baseScreen,
259 __GLXconfig * glxConfig,
260 __GLXcontext * baseShareContext)
262 __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
263 __GLXDRIcontext *context, *shareContext;
264 __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
265 const __DRIcoreExtension *core = screen->core;
266 __DRIcontext *driShare;
268 shareContext = (__GLXDRIcontext *) baseShareContext;
270 driShare = shareContext->driContext;
274 context = calloc(1, sizeof *context);
278 context->base.destroy = __glXDRIcontextDestroy;
279 context->base.makeCurrent = __glXDRIcontextMakeCurrent;
280 context->base.loseCurrent = __glXDRIcontextLoseCurrent;
281 context->base.copy = __glXDRIcontextCopy;
282 context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
284 context->driContext =
285 (*core->createNewContext) (screen->driScreen,
286 config->driConfig, driShare, context);
288 return &context->base;
291 static __GLXdrawable *
292 __glXDRIscreenCreateDrawable(ClientPtr client,
293 __GLXscreen * screen,
296 int type, XID glxDrawId, __GLXconfig * glxConfig)
300 __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
301 __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
302 __GLXDRIdrawable *private;
304 private = calloc(1, sizeof *private);
308 private->screen = driScreen;
309 if (!__glXDrawableInit(&private->base, screen,
310 pDraw, type, glxDrawId, glxConfig)) {
315 private->base.destroy = __glXDRIdrawableDestroy;
316 private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
317 private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
321 CreateGC(pDraw, GCFunction, gcvals, &status, (XID) 0, serverClient);
324 CreateGC(pDraw, GCFunction | GCGraphicsExposures, gcvals, &status,
325 (XID) 0, serverClient);
327 private->driDrawable =
328 (*driScreen->swrast->createNewDrawable) (driScreen->driScreen,
329 config->driConfig, private);
331 return &private->base;
335 swrastGetDrawableInfo(__DRIdrawable * draw,
336 int *x, int *y, int *w, int *h, void *loaderPrivate)
338 __GLXDRIdrawable *drawable = loaderPrivate;
339 DrawablePtr pDraw = drawable->base.pDraw;
348 swrastPutImage(__DRIdrawable * draw, int op,
349 int x, int y, int w, int h, char *data, void *loaderPrivate)
351 __GLXDRIdrawable *drawable = loaderPrivate;
352 DrawablePtr pDraw = drawable->base.pDraw;
356 case __DRI_SWRAST_IMAGE_OP_DRAW:
359 case __DRI_SWRAST_IMAGE_OP_SWAP:
360 gc = drawable->swapgc;
366 ValidateGC(pDraw, gc);
368 gc->ops->PutImage(pDraw, gc, pDraw->depth, x, y, w, h, 0, ZPixmap, data);
372 swrastGetImage(__DRIdrawable * draw,
373 int x, int y, int w, int h, char *data, void *loaderPrivate)
375 __GLXDRIdrawable *drawable = loaderPrivate;
376 DrawablePtr pDraw = drawable->base.pDraw;
377 ScreenPtr pScreen = pDraw->pScreen;
379 pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data);
382 static const __DRIswrastLoaderExtension swrastLoaderExtension = {
383 {__DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION},
384 swrastGetDrawableInfo,
389 static const __DRIextension *loader_extensions[] = {
390 &systemTimeExtension.base,
391 &swrastLoaderExtension.base,
396 initializeExtensions(__GLXDRIscreen * screen)
398 const __DRIextension **extensions;
401 extensions = screen->core->getExtensions(screen->driScreen);
403 for (i = 0; extensions[i]; i++) {
404 #ifdef __DRI_COPY_SUB_BUFFER
405 if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
406 screen->copySubBuffer =
407 (const __DRIcopySubBufferExtension *) extensions[i];
408 /* GLX_MESA_copy_sub_buffer is always enabled. */
412 #ifdef __DRI_TEX_BUFFER
413 if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
414 screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
415 /* GLX_EXT_texture_from_pixmap is always enabled. */
418 /* Ignore unknown extensions */
423 __glXDRIscreenProbe(ScreenPtr pScreen)
425 const char *driverName = "swrast";
426 __GLXDRIscreen *screen;
428 screen = calloc(1, sizeof *screen);
432 screen->base.destroy = __glXDRIscreenDestroy;
433 screen->base.createContext = __glXDRIscreenCreateContext;
434 screen->base.createDrawable = __glXDRIscreenCreateDrawable;
435 screen->base.swapInterval = NULL;
436 screen->base.pScreen = pScreen;
438 screen->driver = glxProbeDriver(driverName,
439 (void **) &screen->core,
440 __DRI_CORE, __DRI_CORE_VERSION,
441 (void **) &screen->swrast,
442 __DRI_SWRAST, __DRI_SWRAST_VERSION);
443 if (screen->driver == NULL) {
448 (*screen->swrast->createNewScreen) (pScreen->myNum,
450 &screen->driConfigs, screen);
452 if (screen->driScreen == NULL) {
453 LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed\n");
457 initializeExtensions(screen);
459 screen->base.fbconfigs = glxConvertConfigs(screen->core, screen->driConfigs,
464 __glXScreenInit(&screen->base, pScreen);
466 screen->base.GLXmajor = 1;
467 screen->base.GLXminor = 4;
469 LogMessage(X_INFO, "AIGLX: Loaded and initialized %s\n", driverName);
471 return &screen->base;
475 dlclose(screen->driver);
479 LogMessage(X_ERROR, "GLX: could not load software renderer\n");
484 _X_EXPORT __GLXprovider __glXDRISWRastProvider = {