~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/gallium/winsys/sw/xlib/xlib_sw_winsys.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
 * 
 
3
 * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
 
4
 * All Rights Reserved.
 
5
 * 
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
 
7
 * copy of this software and associated documentation files (the
 
8
 * "Software"), to deal in the Software without restriction, including
 
9
 * without limitation the rights to use, copy, modify, merge, publish,
 
10
 * distribute, sub license, and/or sell copies of the Software, and to
 
11
 * permit persons to whom the Software is furnished to do so, subject to
 
12
 * the following conditions:
 
13
 * 
 
14
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 
17
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 
18
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
 
19
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 
 
20
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 *
 
22
 * The above copyright notice and this permission notice (including the
 
23
 * next paragraph) shall be included in all copies or substantial portions
 
24
 * of the Software.
 
25
 * 
 
26
 * 
 
27
 **************************************************************************/
 
28
 
 
29
/*
 
30
 * Authors:
 
31
 *   Keith Whitwell
 
32
 *   Brian Paul
 
33
 */
 
34
 
 
35
#include "pipe/p_format.h"
 
36
#include "pipe/p_context.h"
 
37
#include "util/u_inlines.h"
 
38
#include "util/u_format.h"
 
39
#include "util/u_math.h"
 
40
#include "util/u_memory.h"
 
41
 
 
42
#include "state_tracker/xlib_sw_winsys.h"
 
43
 
 
44
#include <X11/Xlib.h>
 
45
#include <X11/Xlibint.h>
 
46
#include <X11/Xutil.h>
 
47
#include <sys/ipc.h>
 
48
#include <sys/shm.h>
 
49
#include <X11/extensions/XShm.h>
 
50
 
 
51
DEBUG_GET_ONCE_BOOL_OPTION(xlib_no_shm, "XLIB_NO_SHM", FALSE)
 
52
 
 
53
/**
 
54
 * Display target for Xlib winsys.
 
55
 * Low-level OS/window system memory buffer
 
56
 */
 
57
struct xm_displaytarget
 
58
{
 
59
   enum pipe_format format;
 
60
   unsigned width;
 
61
   unsigned height;
 
62
   unsigned stride;
 
63
 
 
64
   void *data;
 
65
   void *mapped;
 
66
 
 
67
   Display *display;
 
68
   Visual *visual;
 
69
   XImage *tempImage;
 
70
   GC gc;
 
71
 
 
72
   /* This is the last drawable that this display target was presented
 
73
    * against.  May need to recreate gc, tempImage when this changes??
 
74
    */
 
75
   Drawable drawable;
 
76
 
 
77
   XShmSegmentInfo shminfo;
 
78
   int shm;
 
79
};
 
80
 
 
81
 
 
82
/**
 
83
 * Subclass of sw_winsys for Xlib winsys
 
84
 */
 
85
struct xlib_sw_winsys
 
86
{
 
87
   struct sw_winsys base;
 
88
 
 
89
 
 
90
 
 
91
   Display *display;
 
92
};
 
93
 
 
94
 
 
95
 
 
96
/** Cast wrapper */
 
97
static INLINE struct xm_displaytarget *
 
98
xm_displaytarget( struct sw_displaytarget *dt )
 
99
{
 
100
   return (struct xm_displaytarget *)dt;
 
101
}
 
102
 
 
103
 
 
104
/**
 
105
 * X Shared Memory Image extension code
 
106
 */
 
107
 
 
108
static volatile int mesaXErrorFlag = 0;
 
109
 
 
110
/**
 
111
 * Catches potential Xlib errors.
 
112
 */
 
113
static int
 
114
mesaHandleXError(Display *dpy, XErrorEvent *event)
 
115
{
 
116
   (void) dpy;
 
117
   (void) event;
 
118
   mesaXErrorFlag = 1;
 
119
   return 0;
 
120
}
 
121
 
 
122
 
 
123
static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
 
124
{
 
125
   XShmSegmentInfo *const shminfo = & buf->shminfo;
 
126
 
 
127
   shminfo->shmid = -1;
 
128
   shminfo->shmaddr = (char *) -1;
 
129
 
 
130
   shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
 
131
   if (shminfo->shmid < 0) {
 
132
      return NULL;
 
133
   }
 
134
 
 
135
   shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
 
136
   if (shminfo->shmaddr == (char *) -1) {
 
137
      shmctl(shminfo->shmid, IPC_RMID, 0);
 
138
      return NULL;
 
139
   }
 
140
 
 
141
   shminfo->readOnly = False;
 
142
   return shminfo->shmaddr;
 
143
}
 
144
 
 
145
 
 
146
/**
 
147
 * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
 
148
 */
 
149
static void
 
150
alloc_shm_ximage(struct xm_displaytarget *xm_dt,
 
151
                 struct xlib_drawable *xmb,
 
152
                 unsigned width, unsigned height)
 
153
{
 
154
   /*
 
155
    * We have to do a _lot_ of error checking here to be sure we can
 
156
    * really use the XSHM extension.  It seems different servers trigger
 
157
    * errors at different points if the extension won't work.  Therefore
 
158
    * we have to be very careful...
 
159
    */
 
160
   int (*old_handler)(Display *, XErrorEvent *);
 
161
 
 
162
   xm_dt->tempImage = XShmCreateImage(xm_dt->display,
 
163
                                      xmb->visual,
 
164
                                      xmb->depth,
 
165
                                      ZPixmap,
 
166
                                      NULL,
 
167
                                      &xm_dt->shminfo,
 
168
                                      width, height);
 
169
   if (xm_dt->tempImage == NULL) {
 
170
      xm_dt->shm = 0;
 
171
      return;
 
172
   }
 
173
 
 
174
 
 
175
   mesaXErrorFlag = 0;
 
176
   old_handler = XSetErrorHandler(mesaHandleXError);
 
177
   /* This may trigger the X protocol error we're ready to catch: */
 
178
   XShmAttach(xm_dt->display, &xm_dt->shminfo);
 
179
   XSync(xm_dt->display, False);
 
180
 
 
181
   if (mesaXErrorFlag) {
 
182
      /* we are on a remote display, this error is normal, don't print it */
 
183
      XFlush(xm_dt->display);
 
184
      mesaXErrorFlag = 0;
 
185
      XDestroyImage(xm_dt->tempImage);
 
186
      xm_dt->tempImage = NULL;
 
187
      xm_dt->shm = 0;
 
188
      (void) XSetErrorHandler(old_handler);
 
189
      return;
 
190
   }
 
191
 
 
192
   xm_dt->shm = 1;
 
193
}
 
194
 
 
195
 
 
196
static void
 
197
alloc_ximage(struct xm_displaytarget *xm_dt,
 
198
             struct xlib_drawable *xmb,
 
199
             unsigned width, unsigned height)
 
200
{
 
201
   if (xm_dt->shm) {
 
202
      alloc_shm_ximage(xm_dt, xmb, width, height);
 
203
      return;
 
204
   }
 
205
 
 
206
   xm_dt->tempImage = XCreateImage(xm_dt->display,
 
207
                                   xmb->visual,
 
208
                                   xmb->depth,
 
209
                                   ZPixmap, 0,
 
210
                                   NULL, width, height,
 
211
                                   8, 0);
 
212
}
 
213
 
 
214
static boolean
 
215
xm_is_displaytarget_format_supported( struct sw_winsys *ws,
 
216
                                      unsigned tex_usage,
 
217
                                      enum pipe_format format )
 
218
{
 
219
   /* TODO: check visuals or other sensible thing here */
 
220
   return TRUE;
 
221
}
 
222
 
 
223
 
 
224
static void *
 
225
xm_displaytarget_map(struct sw_winsys *ws,
 
226
                     struct sw_displaytarget *dt,
 
227
                     unsigned flags)
 
228
{
 
229
   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
 
230
   xm_dt->mapped = xm_dt->data;
 
231
   return xm_dt->mapped;
 
232
}
 
233
 
 
234
static void
 
235
xm_displaytarget_unmap(struct sw_winsys *ws,
 
236
                       struct sw_displaytarget *dt)
 
237
{
 
238
   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
 
239
   xm_dt->mapped = NULL;
 
240
}
 
241
 
 
242
static void
 
243
xm_displaytarget_destroy(struct sw_winsys *ws,
 
244
                         struct sw_displaytarget *dt)
 
245
{
 
246
   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
 
247
 
 
248
   if (xm_dt->data) {
 
249
      if (xm_dt->shminfo.shmid >= 0) {
 
250
         shmdt(xm_dt->shminfo.shmaddr);
 
251
         shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
 
252
         
 
253
         xm_dt->shminfo.shmid = -1;
 
254
         xm_dt->shminfo.shmaddr = (char *) -1;
 
255
      }
 
256
      else {
 
257
         FREE(xm_dt->data);
 
258
         if (xm_dt->tempImage && xm_dt->tempImage->data == xm_dt->data) {
 
259
            xm_dt->tempImage->data = NULL;
 
260
         }
 
261
         xm_dt->data = NULL;
 
262
      }
 
263
   }
 
264
 
 
265
   if (xm_dt->tempImage) {
 
266
      XDestroyImage(xm_dt->tempImage);
 
267
      xm_dt->tempImage = NULL;
 
268
   }
 
269
 
 
270
   if (xm_dt->gc)
 
271
      XFreeGC(xm_dt->display, xm_dt->gc);
 
272
 
 
273
   FREE(xm_dt);
 
274
}
 
275
 
 
276
 
 
277
/**
 
278
 * Display/copy the image in the surface into the X window specified
 
279
 * by the XMesaBuffer.
 
280
 */
 
281
static void
 
282
xlib_sw_display(struct xlib_drawable *xlib_drawable,
 
283
                struct sw_displaytarget *dt)
 
284
{
 
285
   static boolean no_swap = 0;
 
286
   static boolean firsttime = 1;
 
287
   struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
 
288
   Display *display = xm_dt->display;
 
289
   XImage *ximage;
 
290
 
 
291
   if (firsttime) {
 
292
      no_swap = getenv("SP_NO_RAST") != NULL;
 
293
      firsttime = 0;
 
294
   }
 
295
 
 
296
   if (no_swap)
 
297
      return;
 
298
 
 
299
   if (xm_dt->drawable != xlib_drawable->drawable) {
 
300
      if (xm_dt->gc) {
 
301
         XFreeGC( display, xm_dt->gc );
 
302
         xm_dt->gc = NULL;
 
303
      }
 
304
 
 
305
      if (xm_dt->tempImage) {
 
306
         XDestroyImage( xm_dt->tempImage );
 
307
         xm_dt->tempImage = NULL;
 
308
      }
 
309
 
 
310
      xm_dt->drawable = xlib_drawable->drawable;
 
311
   }
 
312
 
 
313
   if (xm_dt->tempImage == NULL) {
 
314
      assert(util_format_get_blockwidth(xm_dt->format) == 1);
 
315
      assert(util_format_get_blockheight(xm_dt->format) == 1);
 
316
      alloc_ximage(xm_dt, xlib_drawable,
 
317
                   xm_dt->stride / util_format_get_blocksize(xm_dt->format),
 
318
                   xm_dt->height);
 
319
      if (!xm_dt->tempImage)
 
320
         return;
 
321
   }
 
322
 
 
323
   if (xm_dt->gc == NULL) {
 
324
      xm_dt->gc = XCreateGC( display, xlib_drawable->drawable, 0, NULL );
 
325
      XSetFunction( display, xm_dt->gc, GXcopy );
 
326
   }
 
327
 
 
328
   if (xm_dt->shm)
 
329
   {
 
330
      ximage = xm_dt->tempImage;
 
331
      ximage->data = xm_dt->data;
 
332
 
 
333
      /* _debug_printf("XSHM\n"); */
 
334
      XShmPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
 
335
                   ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
 
336
   }
 
337
   else {
 
338
      /* display image in Window */
 
339
      ximage = xm_dt->tempImage;
 
340
      ximage->data = xm_dt->data;
 
341
 
 
342
      /* check that the XImage has been previously initialized */
 
343
      assert(ximage->format);
 
344
      assert(ximage->bitmap_unit);
 
345
 
 
346
      /* update XImage's fields */
 
347
      ximage->width = xm_dt->width;
 
348
      ximage->height = xm_dt->height;
 
349
      ximage->bytes_per_line = xm_dt->stride;
 
350
 
 
351
      /* _debug_printf("XPUT\n"); */
 
352
      XPutImage(xm_dt->display, xlib_drawable->drawable, xm_dt->gc,
 
353
                ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
 
354
   }
 
355
 
 
356
   XFlush(xm_dt->display);
 
357
}
 
358
 
 
359
/**
 
360
 * Display/copy the image in the surface into the X window specified
 
361
 * by the XMesaBuffer.
 
362
 */
 
363
static void
 
364
xm_displaytarget_display(struct sw_winsys *ws,
 
365
                         struct sw_displaytarget *dt,
 
366
                         void *context_private)
 
367
{
 
368
   struct xlib_drawable *xlib_drawable = (struct xlib_drawable *)context_private;
 
369
   xlib_sw_display(xlib_drawable, dt);
 
370
}
 
371
 
 
372
 
 
373
static struct sw_displaytarget *
 
374
xm_displaytarget_create(struct sw_winsys *winsys,
 
375
                        unsigned tex_usage,
 
376
                        enum pipe_format format,
 
377
                        unsigned width, unsigned height,
 
378
                        unsigned alignment,
 
379
                        unsigned *stride)
 
380
{
 
381
   struct xm_displaytarget *xm_dt;
 
382
   unsigned nblocksy, size;
 
383
 
 
384
   xm_dt = CALLOC_STRUCT(xm_displaytarget);
 
385
   if(!xm_dt)
 
386
      goto no_xm_dt;
 
387
 
 
388
   xm_dt->display = ((struct xlib_sw_winsys *)winsys)->display;
 
389
   xm_dt->format = format;
 
390
   xm_dt->width = width;
 
391
   xm_dt->height = height;
 
392
 
 
393
   nblocksy = util_format_get_nblocksy(format, height);
 
394
   xm_dt->stride = align(util_format_get_stride(format, width), alignment);
 
395
   size = xm_dt->stride * nblocksy;
 
396
 
 
397
   if (!debug_get_option_xlib_no_shm()) {
 
398
      xm_dt->data = alloc_shm(xm_dt, size);
 
399
      if (xm_dt->data) {
 
400
         xm_dt->shm = TRUE;
 
401
      }
 
402
   }
 
403
 
 
404
   if(!xm_dt->data) {
 
405
      xm_dt->data = align_malloc(size, alignment);
 
406
      if(!xm_dt->data)
 
407
         goto no_data;
 
408
   }
 
409
 
 
410
   *stride = xm_dt->stride;
 
411
   return (struct sw_displaytarget *)xm_dt;
 
412
 
 
413
no_data:
 
414
   FREE(xm_dt);
 
415
no_xm_dt:
 
416
   return NULL;
 
417
}
 
418
 
 
419
 
 
420
static struct sw_displaytarget *
 
421
xm_displaytarget_from_handle(struct sw_winsys *winsys,
 
422
                             const struct pipe_resource *templet,
 
423
                             struct winsys_handle *whandle,
 
424
                             unsigned *stride)
 
425
{
 
426
   assert(0);
 
427
   return NULL;
 
428
}
 
429
 
 
430
 
 
431
static boolean
 
432
xm_displaytarget_get_handle(struct sw_winsys *winsys,
 
433
                            struct sw_displaytarget *dt,
 
434
                            struct winsys_handle *whandle)
 
435
{
 
436
   assert(0);
 
437
   return FALSE;
 
438
}
 
439
 
 
440
 
 
441
static void
 
442
xm_destroy( struct sw_winsys *ws )
 
443
{
 
444
   FREE(ws);
 
445
}
 
446
 
 
447
 
 
448
struct sw_winsys *
 
449
xlib_create_sw_winsys( Display *display )
 
450
{
 
451
   struct xlib_sw_winsys *ws;
 
452
 
 
453
   ws = CALLOC_STRUCT(xlib_sw_winsys);
 
454
   if (!ws)
 
455
      return NULL;
 
456
 
 
457
   ws->display = display;
 
458
   ws->base.destroy = xm_destroy;
 
459
 
 
460
   ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
 
461
 
 
462
   ws->base.displaytarget_create = xm_displaytarget_create;
 
463
   ws->base.displaytarget_from_handle = xm_displaytarget_from_handle;
 
464
   ws->base.displaytarget_get_handle = xm_displaytarget_get_handle;
 
465
   ws->base.displaytarget_map = xm_displaytarget_map;
 
466
   ws->base.displaytarget_unmap = xm_displaytarget_unmap;
 
467
   ws->base.displaytarget_destroy = xm_displaytarget_destroy;
 
468
 
 
469
   ws->base.displaytarget_display = xm_displaytarget_display;
 
470
 
 
471
   return &ws->base;
 
472
}
 
473