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 "extension_string.h"
53 /* RTLD_LOCAL is not defined on Cygwin */
60 typedef struct __GLXDRIscreen __GLXDRIscreen;
61 typedef struct __GLXDRIcontext __GLXDRIcontext;
62 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
64 struct __GLXDRIscreen {
66 __DRIscreen *driScreen;
69 const __DRIcoreExtension *core;
70 const __DRIswrastExtension *swrast;
71 const __DRIcopySubBufferExtension *copySubBuffer;
72 const __DRItexBufferExtension *texBuffer;
73 const __DRIconfig **driConfigs;
76 struct __GLXDRIcontext {
78 __DRIcontext *driContext;
81 struct __GLXDRIdrawable {
83 __DRIdrawable *driDrawable;
84 __GLXDRIscreen *screen;
86 GCPtr gc; /* scratch GC for span drawing */
87 GCPtr swapgc; /* GC for swapping the color buffers */
91 __glXDRIdrawableDestroy(__GLXdrawable * drawable)
93 __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
94 const __DRIcoreExtension *core = private->screen->core;
96 (*core->destroyDrawable) (private->driDrawable);
98 FreeGC(private->gc, (GContext) 0);
99 FreeGC(private->swapgc, (GContext) 0);
101 __glXDrawableRelease(drawable);
107 __glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable * drawable)
109 __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
110 const __DRIcoreExtension *core = private->screen->core;
112 (*core->swapBuffers) (private->driDrawable);
118 __glXDRIdrawableCopySubBuffer(__GLXdrawable * basePrivate,
119 int x, int y, int w, int h)
121 __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
122 const __DRIcopySubBufferExtension *copySubBuffer =
123 private->screen->copySubBuffer;
126 (*copySubBuffer->copySubBuffer) (private->driDrawable, x, y, w, h);
130 __glXDRIcontextDestroy(__GLXcontext * baseContext)
132 __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
133 __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
135 (*screen->core->destroyContext) (context->driContext);
136 __glXContextDestroy(&context->base);
141 __glXDRIcontextMakeCurrent(__GLXcontext * baseContext)
143 __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
144 __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
145 __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
146 __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
148 return (*screen->core->bindContext) (context->driContext,
149 draw->driDrawable, read->driDrawable);
153 __glXDRIcontextLoseCurrent(__GLXcontext * baseContext)
155 __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
156 __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
158 return (*screen->core->unbindContext) (context->driContext);
162 __glXDRIcontextCopy(__GLXcontext * baseDst, __GLXcontext * baseSrc,
165 __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
166 __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
167 __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
169 return (*screen->core->copyContext) (dst->driContext,
170 src->driContext, mask);
174 __glXDRIbindTexImage(__GLXcontext * baseContext,
175 int buffer, __GLXdrawable * glxPixmap)
177 __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
178 const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
179 __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
181 if (texBuffer == NULL)
184 #if __DRI_TEX_BUFFER_VERSION >= 2
185 if (texBuffer->base.version >= 2 && texBuffer->setTexBuffer2 != NULL) {
186 (*texBuffer->setTexBuffer2) (context->driContext,
188 glxPixmap->format, drawable->driDrawable);
192 texBuffer->setTexBuffer(context->driContext,
193 glxPixmap->target, drawable->driDrawable);
199 __glXDRIreleaseTexImage(__GLXcontext * baseContext,
200 int buffer, __GLXdrawable * pixmap)
202 /* FIXME: Just unbind the texture? */
206 static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
207 __glXDRIbindTexImage,
208 __glXDRIreleaseTexImage
212 __glXDRIscreenDestroy(__GLXscreen * baseScreen)
216 __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
218 (*screen->core->destroyScreen) (screen->driScreen);
220 dlclose(screen->driver);
222 __glXScreenDestroy(baseScreen);
224 if (screen->driConfigs) {
225 for (i = 0; screen->driConfigs[i] != NULL; i++)
226 free((__DRIconfig **) screen->driConfigs[i]);
227 free(screen->driConfigs);
233 static __GLXcontext *
234 __glXDRIscreenCreateContext(__GLXscreen * baseScreen,
235 __GLXconfig * glxConfig,
236 __GLXcontext * baseShareContext,
237 unsigned num_attribs,
238 const uint32_t *attribs,
241 __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
242 __GLXDRIcontext *context, *shareContext;
243 __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
244 const __DRIcoreExtension *core = screen->core;
245 __DRIcontext *driShare;
247 /* DRISWRAST won't support createContextAttribs, so these parameters will
254 shareContext = (__GLXDRIcontext *) baseShareContext;
256 driShare = shareContext->driContext;
260 context = calloc(1, sizeof *context);
264 context->base.destroy = __glXDRIcontextDestroy;
265 context->base.makeCurrent = __glXDRIcontextMakeCurrent;
266 context->base.loseCurrent = __glXDRIcontextLoseCurrent;
267 context->base.copy = __glXDRIcontextCopy;
268 context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
270 context->driContext =
271 (*core->createNewContext) (screen->driScreen,
272 config->driConfig, driShare, context);
274 return &context->base;
277 static __GLXdrawable *
278 __glXDRIscreenCreateDrawable(ClientPtr client,
279 __GLXscreen * screen,
282 int type, XID glxDrawId, __GLXconfig * glxConfig)
286 __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
287 __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
288 __GLXDRIdrawable *private;
290 private = calloc(1, sizeof *private);
294 private->screen = driScreen;
295 if (!__glXDrawableInit(&private->base, screen,
296 pDraw, type, glxDrawId, glxConfig)) {
301 private->base.destroy = __glXDRIdrawableDestroy;
302 private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
303 private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
307 CreateGC(pDraw, GCFunction, gcvals, &status, (XID) 0, serverClient);
310 CreateGC(pDraw, GCFunction | GCGraphicsExposures, gcvals, &status,
311 (XID) 0, serverClient);
313 private->driDrawable =
314 (*driScreen->swrast->createNewDrawable) (driScreen->driScreen,
315 config->driConfig, private);
317 return &private->base;
321 swrastGetDrawableInfo(__DRIdrawable * draw,
322 int *x, int *y, int *w, int *h, void *loaderPrivate)
324 __GLXDRIdrawable *drawable = loaderPrivate;
325 DrawablePtr pDraw = drawable->base.pDraw;
334 swrastPutImage(__DRIdrawable * draw, int op,
335 int x, int y, int w, int h, char *data, void *loaderPrivate)
337 __GLXDRIdrawable *drawable = loaderPrivate;
338 DrawablePtr pDraw = drawable->base.pDraw;
340 __GLXcontext *cx = lastGLContext;
343 case __DRI_SWRAST_IMAGE_OP_DRAW:
346 case __DRI_SWRAST_IMAGE_OP_SWAP:
347 gc = drawable->swapgc;
353 ValidateGC(pDraw, gc);
355 gc->ops->PutImage(pDraw, gc, pDraw->depth, x, y, w, h, 0, ZPixmap, data);
356 if (cx != lastGLContext) {
363 swrastGetImage(__DRIdrawable * draw,
364 int x, int y, int w, int h, char *data, void *loaderPrivate)
366 __GLXDRIdrawable *drawable = loaderPrivate;
367 DrawablePtr pDraw = drawable->base.pDraw;
368 ScreenPtr pScreen = pDraw->pScreen;
369 __GLXcontext *cx = lastGLContext;
371 pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data);
372 if (cx != lastGLContext) {
378 static const __DRIswrastLoaderExtension swrastLoaderExtension = {
379 {__DRI_SWRAST_LOADER, 1},
380 swrastGetDrawableInfo,
385 static const __DRIextension *loader_extensions[] = {
386 &systemTimeExtension.base,
387 &swrastLoaderExtension.base,
392 initializeExtensions(__GLXDRIscreen * screen)
394 const __DRIextension **extensions;
397 extensions = screen->core->getExtensions(screen->driScreen);
399 for (i = 0; extensions[i]; i++) {
400 if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
401 screen->copySubBuffer =
402 (const __DRIcopySubBufferExtension *) extensions[i];
403 /* GLX_MESA_copy_sub_buffer is always enabled. */
406 if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
407 screen->texBuffer = (const __DRItexBufferExtension *) extensions[i];
408 /* GLX_EXT_texture_from_pixmap is always enabled. */
411 /* Ignore unknown extensions */
416 extern glx_func_ptr glXGetProcAddressARB(const char *);
419 __glXDRIscreenProbe(ScreenPtr pScreen)
421 const char *driverName = "swrast";
422 __GLXDRIscreen *screen;
424 screen = calloc(1, sizeof *screen);
428 screen->base.destroy = __glXDRIscreenDestroy;
429 screen->base.createContext = __glXDRIscreenCreateContext;
430 screen->base.createDrawable = __glXDRIscreenCreateDrawable;
431 screen->base.swapInterval = NULL;
432 screen->base.pScreen = pScreen;
434 screen->driver = glxProbeDriver(driverName,
435 (void **) &screen->core,
437 (void **) &screen->swrast,
439 if (screen->driver == NULL) {
444 (*screen->swrast->createNewScreen) (pScreen->myNum,
446 &screen->driConfigs, screen);
448 if (screen->driScreen == NULL) {
449 LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed\n");
453 initializeExtensions(screen);
455 screen->base.fbconfigs = glxConvertConfigs(screen->core, screen->driConfigs,
460 __glXScreenInit(&screen->base, pScreen);
462 screen->base.GLXmajor = 1;
463 screen->base.GLXminor = 4;
465 __glXsetGetProcAddress(glXGetProcAddressARB);
467 LogMessage(X_INFO, "AIGLX: Loaded and initialized %s\n", driverName);
469 return &screen->base;
473 dlclose(screen->driver);
477 LogMessage(X_ERROR, "GLX: could not load software renderer\n");
482 _X_EXPORT __GLXprovider __glXDRISWRastProvider = {