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

« back to all changes in this revision

Viewing changes to src/gallium/state_trackers/egl/fbdev/native_fbdev.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
 * Mesa 3-D graphics library
 
3
 * Version:  7.9
 
4
 *
 
5
 * Copyright (C) 2010 LunarG Inc.
 
6
 *
 
7
 * Permission is hereby granted, free of charge, to any person obtaining a
 
8
 * copy of this software and associated documentation files (the "Software"),
 
9
 * to deal in the Software without restriction, including without limitation
 
10
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
11
 * and/or sell copies of the Software, and to permit persons to whom the
 
12
 * Software is furnished to do so, subject to the following conditions:
 
13
 *
 
14
 * The above copyright notice and this permission notice shall be included
 
15
 * in all copies or substantial portions of the Software.
 
16
 *
 
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
23
 * DEALINGS IN THE SOFTWARE.
 
24
 *
 
25
 * Authors:
 
26
 *    Chia-I Wu <olv@lunarg.com>
 
27
 */
 
28
 
 
29
#include <sys/ioctl.h>
 
30
#include <sys/types.h>
 
31
#include <sys/stat.h>
 
32
#include <fcntl.h>
 
33
#include <linux/fb.h>
 
34
 
 
35
#include "pipe/p_screen.h"
 
36
#include "util/u_memory.h"
 
37
#include "util/u_inlines.h"
 
38
#include "util/u_pointer.h"
 
39
 
 
40
#include "common/native.h"
 
41
#include "common/native_helper.h"
 
42
#include "fbdev/fbdev_sw_winsys.h"
 
43
 
 
44
struct fbdev_display {
 
45
   struct native_display base;
 
46
 
 
47
   int fd;
 
48
   struct native_event_handler *event_handler;
 
49
 
 
50
   struct fb_fix_screeninfo finfo;
 
51
   struct fb_var_screeninfo vinfo;
 
52
 
 
53
   struct native_config config;
 
54
   struct native_connector connector;
 
55
   struct native_mode mode;
 
56
 
 
57
   struct fbdev_surface *current_surface;
 
58
};
 
59
 
 
60
struct fbdev_surface {
 
61
   struct native_surface base;
 
62
 
 
63
   struct fbdev_display *fbdpy;
 
64
   struct resource_surface *rsurf;
 
65
   int width, height;
 
66
 
 
67
   unsigned int sequence_number;
 
68
 
 
69
   boolean is_current;
 
70
};
 
71
 
 
72
static INLINE struct fbdev_display *
 
73
fbdev_display(const struct native_display *ndpy)
 
74
{
 
75
   return (struct fbdev_display *) ndpy;
 
76
}
 
77
 
 
78
static INLINE struct fbdev_surface *
 
79
fbdev_surface(const struct native_surface *nsurf)
 
80
{
 
81
   return (struct fbdev_surface *) nsurf;
 
82
}
 
83
 
 
84
static boolean
 
85
fbdev_surface_validate(struct native_surface *nsurf, uint attachment_mask,
 
86
                     unsigned int *seq_num, struct pipe_resource **textures,
 
87
                     int *width, int *height)
 
88
{
 
89
   struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
 
90
 
 
91
   if (!resource_surface_add_resources(fbsurf->rsurf, attachment_mask))
 
92
      return FALSE;
 
93
   if (textures)
 
94
      resource_surface_get_resources(fbsurf->rsurf, textures, attachment_mask);
 
95
 
 
96
   if (seq_num)
 
97
      *seq_num = fbsurf->sequence_number;
 
98
   if (width)
 
99
      *width = fbsurf->width;
 
100
   if (height)
 
101
      *height = fbsurf->height;
 
102
 
 
103
   return TRUE;
 
104
}
 
105
 
 
106
static boolean
 
107
fbdev_surface_flush_frontbuffer(struct native_surface *nsurf)
 
108
{
 
109
   struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
 
110
 
 
111
   if (!fbsurf->is_current)
 
112
      return TRUE;
 
113
 
 
114
   return resource_surface_present(fbsurf->rsurf,
 
115
         NATIVE_ATTACHMENT_FRONT_LEFT, NULL);
 
116
}
 
117
 
 
118
static boolean
 
119
fbdev_surface_swap_buffers(struct native_surface *nsurf)
 
120
{
 
121
   struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
 
122
   struct fbdev_display *fbdpy = fbsurf->fbdpy;
 
123
   boolean ret = TRUE;
 
124
 
 
125
   if (fbsurf->is_current) {
 
126
      ret = resource_surface_present(fbsurf->rsurf,
 
127
            NATIVE_ATTACHMENT_BACK_LEFT, NULL);
 
128
   }
 
129
 
 
130
   resource_surface_swap_buffers(fbsurf->rsurf,
 
131
         NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
 
132
   /* the front/back textures are swapped */
 
133
   fbsurf->sequence_number++;
 
134
   fbdpy->event_handler->invalid_surface(&fbdpy->base,
 
135
         &fbsurf->base, fbsurf->sequence_number);
 
136
 
 
137
   return ret;
 
138
}
 
139
 
 
140
static void
 
141
fbdev_surface_wait(struct native_surface *nsurf)
 
142
{
 
143
   /* no-op */
 
144
}
 
145
 
 
146
static void
 
147
fbdev_surface_destroy(struct native_surface *nsurf)
 
148
{
 
149
   struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
 
150
 
 
151
   resource_surface_destroy(fbsurf->rsurf);
 
152
   FREE(fbsurf);
 
153
}
 
154
 
 
155
static struct native_surface *
 
156
fbdev_display_create_scanout_surface(struct native_display *ndpy,
 
157
                                   const struct native_config *nconf,
 
158
                                   uint width, uint height)
 
159
{
 
160
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
161
   struct fbdev_surface *fbsurf;
 
162
 
 
163
   fbsurf = CALLOC_STRUCT(fbdev_surface);
 
164
   if (!fbsurf)
 
165
      return NULL;
 
166
 
 
167
   fbsurf->fbdpy = fbdpy;
 
168
   fbsurf->width = width;
 
169
   fbsurf->height = height;
 
170
 
 
171
   fbsurf->rsurf = resource_surface_create(fbdpy->base.screen,
 
172
         nconf->color_format,
 
173
         PIPE_BIND_RENDER_TARGET |
 
174
         PIPE_BIND_DISPLAY_TARGET |
 
175
         PIPE_BIND_SCANOUT);
 
176
   if (!fbsurf->rsurf) {
 
177
      FREE(fbsurf);
 
178
      return NULL;
 
179
   }
 
180
 
 
181
   resource_surface_set_size(fbsurf->rsurf, fbsurf->width, fbsurf->height);
 
182
 
 
183
   fbsurf->base.destroy = fbdev_surface_destroy;
 
184
   fbsurf->base.swap_buffers = fbdev_surface_swap_buffers;
 
185
   fbsurf->base.flush_frontbuffer = fbdev_surface_flush_frontbuffer;
 
186
   fbsurf->base.validate = fbdev_surface_validate;
 
187
   fbsurf->base.wait = fbdev_surface_wait;
 
188
 
 
189
   return &fbsurf->base;
 
190
}
 
191
 
 
192
static boolean
 
193
fbdev_display_program(struct native_display *ndpy, int crtc_idx,
 
194
                      struct native_surface *nsurf, uint x, uint y,
 
195
                      const struct native_connector **nconns, int num_nconns,
 
196
                      const struct native_mode *nmode)
 
197
{
 
198
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
199
   struct fbdev_surface *fbsurf = fbdev_surface(nsurf);
 
200
 
 
201
   if (x || y)
 
202
      return FALSE;
 
203
 
 
204
   if (fbdpy->current_surface) {
 
205
      if (fbdpy->current_surface == fbsurf)
 
206
         return TRUE;
 
207
      fbdpy->current_surface->is_current = FALSE;
 
208
   }
 
209
 
 
210
   if (fbsurf)
 
211
      fbsurf->is_current = TRUE;
 
212
   fbdpy->current_surface = fbsurf;
 
213
 
 
214
   return TRUE;
 
215
}
 
216
 
 
217
static const struct native_mode **
 
218
fbdev_display_get_modes(struct native_display *ndpy,
 
219
                      const struct native_connector *nconn,
 
220
                      int *num_modes)
 
221
{
 
222
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
223
   const struct native_mode **modes;
 
224
 
 
225
   modes = MALLOC(sizeof(*modes));
 
226
   if (modes) {
 
227
      modes[0] = &fbdpy->mode;
 
228
      if (num_modes)
 
229
         *num_modes = 1;
 
230
   }
 
231
 
 
232
   return modes;
 
233
}
 
234
 
 
235
static const struct native_connector **
 
236
fbdev_display_get_connectors(struct native_display *ndpy, int *num_connectors,
 
237
                           int *num_crtc)
 
238
{
 
239
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
240
   const struct native_connector **connectors;
 
241
 
 
242
   connectors = MALLOC(sizeof(*connectors));
 
243
   if (connectors) {
 
244
      connectors[0] = &fbdpy->connector;
 
245
      if (num_connectors)
 
246
         *num_connectors = 1;
 
247
   }
 
248
 
 
249
   return connectors;
 
250
}
 
251
 
 
252
static struct native_display_modeset fbdev_display_modeset = {
 
253
   .get_connectors = fbdev_display_get_connectors,
 
254
   .get_modes = fbdev_display_get_modes,
 
255
   .create_scanout_surface = fbdev_display_create_scanout_surface,
 
256
   .program = fbdev_display_program
 
257
};
 
258
 
 
259
static const struct native_config **
 
260
fbdev_display_get_configs(struct native_display *ndpy, int *num_configs)
 
261
{
 
262
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
263
   const struct native_config **configs;
 
264
 
 
265
   configs = MALLOC(sizeof(*configs));
 
266
   if (configs) {
 
267
      configs[0] = &fbdpy->config;
 
268
      if (num_configs)
 
269
         *num_configs = 1;
 
270
   }
 
271
 
 
272
   return configs;
 
273
}
 
274
 
 
275
static int
 
276
fbdev_display_get_param(struct native_display *ndpy,
 
277
                      enum native_param_type param)
 
278
{
 
279
   int val;
 
280
 
 
281
   switch (param) {
 
282
   default:
 
283
      val = 0;
 
284
      break;
 
285
   }
 
286
 
 
287
   return val;
 
288
}
 
289
 
 
290
static void
 
291
fbdev_display_destroy(struct native_display *ndpy)
 
292
{
 
293
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
294
 
 
295
   fbdpy->base.screen->destroy(fbdpy->base.screen);
 
296
   close(fbdpy->fd);
 
297
   FREE(fbdpy);
 
298
}
 
299
 
 
300
static boolean
 
301
fbdev_display_init_modes(struct native_display *ndpy)
 
302
{
 
303
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
304
   struct native_mode *nmode = &fbdpy->mode;
 
305
 
 
306
   nmode->desc = "Current Mode";
 
307
   nmode->width = fbdpy->vinfo.xres;
 
308
   nmode->height = fbdpy->vinfo.yres;
 
309
   nmode->refresh_rate = 60 * 1000; /* dummy */
 
310
 
 
311
   return TRUE;
 
312
}
 
313
 
 
314
static boolean
 
315
fbdev_display_init_connectors(struct native_display *ndpy)
 
316
{
 
317
   return TRUE;
 
318
}
 
319
 
 
320
static enum pipe_format
 
321
vinfo_to_format(const struct fb_var_screeninfo *vinfo)
 
322
{
 
323
   enum pipe_format format = PIPE_FORMAT_NONE;
 
324
 
 
325
   switch (vinfo->bits_per_pixel) {
 
326
   case 32:
 
327
      if (vinfo->red.length == 8 &&
 
328
          vinfo->green.length == 8 &&
 
329
          vinfo->blue.length == 8) {
 
330
         format = (vinfo->transp.length == 8) ?
 
331
            PIPE_FORMAT_B8G8R8A8_UNORM : PIPE_FORMAT_B8G8R8X8_UNORM;
 
332
      }
 
333
      break;
 
334
   case 16:
 
335
      if (vinfo->red.length == 5 &&
 
336
          vinfo->green.length == 6 &&
 
337
          vinfo->blue.length == 5 &&
 
338
          vinfo->transp.length == 0)
 
339
         format = PIPE_FORMAT_B5G6R5_UNORM;
 
340
      break;
 
341
   default:
 
342
      break;
 
343
   }
 
344
 
 
345
   return format;
 
346
}
 
347
 
 
348
static boolean
 
349
fbdev_display_init_configs(struct native_display *ndpy)
 
350
{
 
351
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
352
   struct native_config *nconf = &fbdpy->config;
 
353
 
 
354
   nconf->color_format = vinfo_to_format(&fbdpy->vinfo);
 
355
   if (nconf->color_format == PIPE_FORMAT_NONE)
 
356
      return FALSE;
 
357
 
 
358
   nconf->buffer_mask =
 
359
      (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
 
360
      (1 << NATIVE_ATTACHMENT_BACK_LEFT);
 
361
 
 
362
   nconf->scanout_bit = TRUE;
 
363
 
 
364
   return TRUE;
 
365
}
 
366
 
 
367
static boolean
 
368
fbdev_display_init(struct native_display *ndpy)
 
369
{
 
370
   struct fbdev_display *fbdpy = fbdev_display(ndpy);
 
371
   struct sw_winsys *ws;
 
372
 
 
373
   if (ioctl(fbdpy->fd, FBIOGET_FSCREENINFO, &fbdpy->finfo))
 
374
      return FALSE;
 
375
 
 
376
   if (ioctl(fbdpy->fd, FBIOGET_VSCREENINFO, &fbdpy->vinfo))
 
377
      return FALSE;
 
378
 
 
379
   if (fbdpy->finfo.visual != FB_VISUAL_TRUECOLOR ||
 
380
       fbdpy->finfo.type != FB_TYPE_PACKED_PIXELS)
 
381
      return FALSE;
 
382
 
 
383
   if (!fbdev_display_init_configs(&fbdpy->base) ||
 
384
       !fbdev_display_init_connectors(&fbdpy->base) ||
 
385
       !fbdev_display_init_modes(&fbdpy->base))
 
386
      return FALSE;
 
387
 
 
388
   ws = fbdev_create_sw_winsys(fbdpy->fd, fbdpy->config.color_format);
 
389
   if (ws) {
 
390
      fbdpy->base.screen =
 
391
         fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws);
 
392
   }
 
393
 
 
394
   if (fbdpy->base.screen) {
 
395
      if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
 
396
               fbdpy->config.color_format, PIPE_TEXTURE_2D, 0,
 
397
               PIPE_BIND_RENDER_TARGET, 0)) {
 
398
         fbdpy->base.screen->destroy(fbdpy->base.screen);
 
399
         fbdpy->base.screen = NULL;
 
400
      }
 
401
   }
 
402
 
 
403
   return (fbdpy->base.screen != NULL);
 
404
}
 
405
 
 
406
static struct native_display *
 
407
fbdev_display_create(int fd, struct native_event_handler *event_handler,
 
408
                     void *user_data)
 
409
{
 
410
   struct fbdev_display *fbdpy;
 
411
 
 
412
   fbdpy = CALLOC_STRUCT(fbdev_display);
 
413
   if (!fbdpy)
 
414
      return NULL;
 
415
 
 
416
   fbdpy->fd = fd;
 
417
   fbdpy->event_handler = event_handler;
 
418
   fbdpy->base.user_data = user_data;
 
419
 
 
420
   if (!fbdev_display_init(&fbdpy->base)) {
 
421
      FREE(fbdpy);
 
422
      return NULL;
 
423
   }
 
424
 
 
425
   fbdpy->base.destroy = fbdev_display_destroy;
 
426
   fbdpy->base.get_param = fbdev_display_get_param;
 
427
   fbdpy->base.get_configs = fbdev_display_get_configs;
 
428
 
 
429
   fbdpy->base.modeset = &fbdev_display_modeset;
 
430
 
 
431
   return &fbdpy->base;
 
432
}
 
433
 
 
434
static struct native_display *
 
435
native_create_display(void *dpy, struct native_event_handler *event_handler,
 
436
                      void *user_data)
 
437
{
 
438
   struct native_display *ndpy;
 
439
   int fd;
 
440
 
 
441
   /* well, this makes fd 0 being ignored */
 
442
   if (!dpy) {
 
443
      fd = open("/dev/fb0", O_RDWR);
 
444
   }
 
445
   else {
 
446
      fd = dup((int) pointer_to_intptr(dpy));
 
447
   }
 
448
   if (fd < 0)
 
449
      return NULL;
 
450
 
 
451
   ndpy = fbdev_display_create(fd, event_handler, user_data);
 
452
   if (!ndpy)
 
453
      close(fd);
 
454
 
 
455
   return ndpy;
 
456
}
 
457
 
 
458
static const struct native_platform fbdev_platform = {
 
459
   "FBDEV", /* name */
 
460
   native_create_display
 
461
};
 
462
 
 
463
const struct native_platform *
 
464
native_get_fbdev_platform(void)
 
465
{
 
466
   return &fbdev_platform;
 
467
}