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
);
173 #ifdef __DRI_TEX_BUFFER
176 __glXDRIbindTexImage(__GLXcontext
* baseContext
,
177 int buffer
, __GLXdrawable
* glxPixmap
)
179 __GLXDRIdrawable
*drawable
= (__GLXDRIdrawable
*) glxPixmap
;
180 const __DRItexBufferExtension
*texBuffer
= drawable
->screen
->texBuffer
;
181 __GLXDRIcontext
*context
= (__GLXDRIcontext
*) baseContext
;
183 if (texBuffer
== NULL
)
186 #if __DRI_TEX_BUFFER_VERSION >= 2
187 if (texBuffer
->base
.version
>= 2 && texBuffer
->setTexBuffer2
!= NULL
) {
188 (*texBuffer
->setTexBuffer2
) (context
->driContext
,
190 glxPixmap
->format
, drawable
->driDrawable
);
194 texBuffer
->setTexBuffer(context
->driContext
,
195 glxPixmap
->target
, drawable
->driDrawable
);
201 __glXDRIreleaseTexImage(__GLXcontext
* baseContext
,
202 int buffer
, __GLXdrawable
* pixmap
)
204 /* FIXME: Just unbind the texture? */
211 __glXDRIbindTexImage(__GLXcontext
* baseContext
,
212 int buffer
, __GLXdrawable
* glxPixmap
)
218 __glXDRIreleaseTexImage(__GLXcontext
* baseContext
,
219 int buffer
, __GLXdrawable
* pixmap
)
226 static __GLXtextureFromPixmap __glXDRItextureFromPixmap
= {
227 __glXDRIbindTexImage
,
228 __glXDRIreleaseTexImage
232 __glXDRIscreenDestroy(__GLXscreen
* baseScreen
)
236 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*) baseScreen
;
238 (*screen
->core
->destroyScreen
) (screen
->driScreen
);
240 dlclose(screen
->driver
);
242 __glXScreenDestroy(baseScreen
);
244 if (screen
->driConfigs
) {
245 for (i
= 0; screen
->driConfigs
[i
] != NULL
; i
++)
246 free((__DRIconfig
**) screen
->driConfigs
[i
]);
247 free(screen
->driConfigs
);
253 static __GLXcontext
*
254 __glXDRIscreenCreateContext(__GLXscreen
* baseScreen
,
255 __GLXconfig
* glxConfig
,
256 __GLXcontext
* baseShareContext
,
257 unsigned num_attribs
,
258 const uint32_t *attribs
,
261 __GLXDRIscreen
*screen
= (__GLXDRIscreen
*) baseScreen
;
262 __GLXDRIcontext
*context
, *shareContext
;
263 __GLXDRIconfig
*config
= (__GLXDRIconfig
*) glxConfig
;
264 const __DRIcoreExtension
*core
= screen
->core
;
265 __DRIcontext
*driShare
;
267 /* DRISWRAST won't support createContextAttribs, so these parameters will
274 shareContext
= (__GLXDRIcontext
*) baseShareContext
;
276 driShare
= shareContext
->driContext
;
280 context
= calloc(1, sizeof *context
);
284 context
->base
.destroy
= __glXDRIcontextDestroy
;
285 context
->base
.makeCurrent
= __glXDRIcontextMakeCurrent
;
286 context
->base
.loseCurrent
= __glXDRIcontextLoseCurrent
;
287 context
->base
.copy
= __glXDRIcontextCopy
;
288 context
->base
.textureFromPixmap
= &__glXDRItextureFromPixmap
;
290 context
->driContext
=
291 (*core
->createNewContext
) (screen
->driScreen
,
292 config
->driConfig
, driShare
, context
);
294 return &context
->base
;
297 static __GLXdrawable
*
298 __glXDRIscreenCreateDrawable(ClientPtr client
,
299 __GLXscreen
* screen
,
302 int type
, XID glxDrawId
, __GLXconfig
* glxConfig
)
306 __GLXDRIscreen
*driScreen
= (__GLXDRIscreen
*) screen
;
307 __GLXDRIconfig
*config
= (__GLXDRIconfig
*) glxConfig
;
308 __GLXDRIdrawable
*private;
310 private = calloc(1, sizeof *private);
314 private->screen
= driScreen
;
315 if (!__glXDrawableInit(&private->base
, screen
,
316 pDraw
, type
, glxDrawId
, glxConfig
)) {
321 private->base
.destroy
= __glXDRIdrawableDestroy
;
322 private->base
.swapBuffers
= __glXDRIdrawableSwapBuffers
;
323 private->base
.copySubBuffer
= __glXDRIdrawableCopySubBuffer
;
327 CreateGC(pDraw
, GCFunction
, gcvals
, &status
, (XID
) 0, serverClient
);
330 CreateGC(pDraw
, GCFunction
| GCGraphicsExposures
, gcvals
, &status
,
331 (XID
) 0, serverClient
);
333 private->driDrawable
=
334 (*driScreen
->swrast
->createNewDrawable
) (driScreen
->driScreen
,
335 config
->driConfig
, private);
337 return &private->base
;
341 swrastGetDrawableInfo(__DRIdrawable
* draw
,
342 int *x
, int *y
, int *w
, int *h
, void *loaderPrivate
)
344 __GLXDRIdrawable
*drawable
= loaderPrivate
;
345 DrawablePtr pDraw
= drawable
->base
.pDraw
;
354 swrastPutImage(__DRIdrawable
* draw
, int op
,
355 int x
, int y
, int w
, int h
, char *data
, void *loaderPrivate
)
357 __GLXDRIdrawable
*drawable
= loaderPrivate
;
358 DrawablePtr pDraw
= drawable
->base
.pDraw
;
362 case __DRI_SWRAST_IMAGE_OP_DRAW
:
365 case __DRI_SWRAST_IMAGE_OP_SWAP
:
366 gc
= drawable
->swapgc
;
372 ValidateGC(pDraw
, gc
);
374 gc
->ops
->PutImage(pDraw
, gc
, pDraw
->depth
, x
, y
, w
, h
, 0, ZPixmap
, data
);
378 swrastGetImage(__DRIdrawable
* draw
,
379 int x
, int y
, int w
, int h
, char *data
, void *loaderPrivate
)
381 __GLXDRIdrawable
*drawable
= loaderPrivate
;
382 DrawablePtr pDraw
= drawable
->base
.pDraw
;
383 ScreenPtr pScreen
= pDraw
->pScreen
;
385 pScreen
->GetImage(pDraw
, x
, y
, w
, h
, ZPixmap
, ~0L, data
);
388 static const __DRIswrastLoaderExtension swrastLoaderExtension
= {
389 {__DRI_SWRAST_LOADER
, 1},
390 swrastGetDrawableInfo
,
395 static const __DRIextension
*loader_extensions
[] = {
396 &systemTimeExtension
.base
,
397 &swrastLoaderExtension
.base
,
402 initializeExtensions(__GLXDRIscreen
* screen
)
404 const __DRIextension
**extensions
;
407 extensions
= screen
->core
->getExtensions(screen
->driScreen
);
409 for (i
= 0; extensions
[i
]; i
++) {
410 #ifdef __DRI_COPY_SUB_BUFFER
411 if (strcmp(extensions
[i
]->name
, __DRI_COPY_SUB_BUFFER
) == 0) {
412 screen
->copySubBuffer
=
413 (const __DRIcopySubBufferExtension
*) extensions
[i
];
414 /* GLX_MESA_copy_sub_buffer is always enabled. */
418 #ifdef __DRI_TEX_BUFFER
419 if (strcmp(extensions
[i
]->name
, __DRI_TEX_BUFFER
) == 0) {
420 screen
->texBuffer
= (const __DRItexBufferExtension
*) extensions
[i
];
421 /* GLX_EXT_texture_from_pixmap is always enabled. */
424 /* Ignore unknown extensions */
429 extern glx_func_ptr
glXGetProcAddressARB(const char *);
432 __glXDRIscreenProbe(ScreenPtr pScreen
)
434 const char *driverName
= "swrast";
435 __GLXDRIscreen
*screen
;
437 screen
= calloc(1, sizeof *screen
);
441 screen
->base
.destroy
= __glXDRIscreenDestroy
;
442 screen
->base
.createContext
= __glXDRIscreenCreateContext
;
443 screen
->base
.createDrawable
= __glXDRIscreenCreateDrawable
;
444 screen
->base
.swapInterval
= NULL
;
445 screen
->base
.pScreen
= pScreen
;
447 screen
->driver
= glxProbeDriver(driverName
,
448 (void **) &screen
->core
,
450 (void **) &screen
->swrast
,
452 if (screen
->driver
== NULL
) {
457 (*screen
->swrast
->createNewScreen
) (pScreen
->myNum
,
459 &screen
->driConfigs
, screen
);
461 if (screen
->driScreen
== NULL
) {
462 LogMessage(X_ERROR
, "AIGLX error: Calling driver entry point failed\n");
466 initializeExtensions(screen
);
468 screen
->base
.fbconfigs
= glxConvertConfigs(screen
->core
, screen
->driConfigs
,
473 __glXScreenInit(&screen
->base
, pScreen
);
475 screen
->base
.GLXmajor
= 1;
476 screen
->base
.GLXminor
= 4;
478 __glXsetGetProcAddress(glXGetProcAddressARB
);
480 LogMessage(X_INFO
, "AIGLX: Loaded and initialized %s\n", driverName
);
482 return &screen
->base
;
486 dlclose(screen
->driver
);
490 LogMessage(X_ERROR
, "GLX: could not load software renderer\n");
495 _X_EXPORT __GLXprovider __glXDRISWRastProvider
= {