~gma500/+junk/gma500-maverick

« back to all changes in this revision

Viewing changes to xpsb-glx/mesa/src/mesa/drivers/fbdev/glfbdev.c

  • Committer: Luca Forina
  • Date: 2011-02-14 09:55:00 UTC
  • Revision ID: luca.forina@gmail.com-20110214095500-kq7o333fbjuoquqs
new commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Mesa 3-D graphics library
 
3
 * Version:  7.1
 
4
 *
 
5
 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
 
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
 
18
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
20
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
21
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
22
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
23
 */
 
24
 
 
25
 
 
26
/*
 
27
 * OpenGL (Mesa) interface for fbdev.
 
28
 * For info about fbdev:
 
29
 * http://www.tldp.org/HOWTO/Framebuffer-HOWTO.html
 
30
 *
 
31
 * known VGA modes
 
32
 * Colours   640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
 
33
 * --------+--------------------------------------------------------------
 
34
 *  4 bits |    ?       ?     0x302      ?        ?        ?         ?
 
35
 *  8 bits |  0x300   0x301   0x303    0x305    0x161    0x307     0x31C
 
36
 * 15 bits |    ?     0x310   0x313    0x316    0x162    0x319     0x31D
 
37
 * 16 bits |    ?     0x311   0x314    0x317    0x163    0x31A     0x31E
 
38
 * 24 bits |    ?     0x312   0x315    0x318      ?      0x31B     0x31F
 
39
 * 32 bits |    ?       ?       ?        ?      0x164      ?
 
40
 */
 
41
 
 
42
#ifdef USE_GLFBDEV_DRIVER
 
43
 
 
44
#include <linux/fb.h>
 
45
#include "GL/glfbdev.h"
 
46
#include "main/glheader.h"
 
47
#include "main/buffers.h"
 
48
#include "main/context.h"
 
49
#include "main/extensions.h"
 
50
#include "main/fbobject.h"
 
51
#include "main/framebuffer.h"
 
52
#include "main/imports.h"
 
53
#include "main/renderbuffer.h"
 
54
#include "main/texformat.h"
 
55
#include "main/teximage.h"
 
56
#include "main/texstore.h"
 
57
#include "vbo/vbo.h"
 
58
#include "swrast/swrast.h"
 
59
#include "swrast_setup/swrast_setup.h"
 
60
#include "tnl/tnl.h"
 
61
#include "tnl/t_context.h"
 
62
#include "tnl/t_pipeline.h"
 
63
#include "drivers/common/driverfuncs.h"
 
64
 
 
65
 
 
66
/**
 
67
 * Pixel formats we support:
 
68
 */
 
69
#define PF_B8G8R8     1
 
70
#define PF_B8G8R8A8   2
 
71
#define PF_B5G6R5     3
 
72
#define PF_B5G5R5     4
 
73
#define PF_CI8        5
 
74
 
 
75
 
 
76
/**
 
77
 * Derived from Mesa's GLvisual class.
 
78
 */
 
79
struct GLFBDevVisualRec {
 
80
   GLvisual glvisual;              /* base class */
 
81
   struct fb_fix_screeninfo fix;
 
82
   struct fb_var_screeninfo var;
 
83
   int pixelFormat;
 
84
};
 
85
 
 
86
/**
 
87
 * Derived from Mesa's GLframebuffer class.
 
88
 */
 
89
struct GLFBDevBufferRec {
 
90
   GLframebuffer glframebuffer;    /* base class */
 
91
   GLFBDevVisualPtr visual;
 
92
   struct fb_fix_screeninfo fix;
 
93
   struct fb_var_screeninfo var;
 
94
   size_t size;                    /* color buffer size in bytes */
 
95
   GLuint bytesPerPixel;
 
96
};
 
97
 
 
98
/**
 
99
 * Derived from Mesa's GLcontext class.
 
100
 */
 
101
struct GLFBDevContextRec {
 
102
   GLcontext glcontext;            /* base class */
 
103
   GLFBDevVisualPtr visual;
 
104
   GLFBDevBufferPtr drawBuffer;
 
105
   GLFBDevBufferPtr readBuffer;
 
106
   GLFBDevBufferPtr curBuffer;
 
107
};
 
108
 
 
109
/**
 
110
 * Derived from Mesa's gl_renderbuffer class.
 
111
 */
 
112
struct GLFBDevRenderbufferRec {
 
113
   struct gl_renderbuffer Base;
 
114
   GLubyte *bottom;                /* pointer to last row */
 
115
   GLuint rowStride;               /* in bytes */
 
116
   GLboolean mallocedBuffer;
 
117
};
 
118
 
 
119
 
 
120
/**********************************************************************/
 
121
/* Internal device driver functions                                   */
 
122
/**********************************************************************/
 
123
 
 
124
 
 
125
static const GLubyte *
 
126
get_string(GLcontext *ctx, GLenum pname)
 
127
{
 
128
   (void) ctx;
 
129
   switch (pname) {
 
130
      case GL_RENDERER:
 
131
         return (const GLubyte *) "Mesa glfbdev";
 
132
      default:
 
133
         return NULL;
 
134
   }
 
135
}
 
136
 
 
137
 
 
138
static void
 
139
update_state( GLcontext *ctx, GLuint new_state )
 
140
{
 
141
   /* not much to do here - pass it on */
 
142
   _swrast_InvalidateState( ctx, new_state );
 
143
   _swsetup_InvalidateState( ctx, new_state );
 
144
   _vbo_InvalidateState( ctx, new_state );
 
145
   _tnl_InvalidateState( ctx, new_state );
 
146
}
 
147
 
 
148
 
 
149
static void
 
150
get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
 
151
{
 
152
   const GLFBDevBufferPtr fbdevbuffer = (GLFBDevBufferPtr) buffer;
 
153
   *width = fbdevbuffer->var.xres;
 
154
   *height = fbdevbuffer->var.yres;
 
155
}
 
156
 
 
157
 
 
158
/**
 
159
 * We only implement this function as a mechanism to check if the
 
160
 * framebuffer size has changed (and update corresponding state).
 
161
 */
 
162
static void
 
163
viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
 
164
{
 
165
   GLuint newWidth, newHeight;
 
166
   GLframebuffer *buffer;
 
167
 
 
168
   buffer = ctx->WinSysDrawBuffer;
 
169
   get_buffer_size( buffer, &newWidth, &newHeight );
 
170
   if (buffer->Width != newWidth || buffer->Height != newHeight) {
 
171
      _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
 
172
   }
 
173
 
 
174
   buffer = ctx->WinSysReadBuffer;
 
175
   get_buffer_size( buffer, &newWidth, &newHeight );
 
176
   if (buffer->Width != newWidth || buffer->Height != newHeight) {
 
177
      _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight );
 
178
   }
 
179
}
 
180
 
 
181
 
 
182
/*
 
183
 * Generate code for span functions.
 
184
 */
 
185
 
 
186
/* 24-bit BGR */
 
187
#define NAME(PREFIX) PREFIX##_B8G8R8
 
188
#define RB_TYPE GLubyte
 
189
#define SPAN_VARS \
 
190
   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 
191
#define INIT_PIXEL_PTR(P, X, Y) \
 
192
   GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 3
 
193
#define INC_PIXEL_PTR(P) P += 3
 
194
#define STORE_PIXEL(DST, X, Y, VALUE) \
 
195
   DST[0] = VALUE[BCOMP];  \
 
196
   DST[1] = VALUE[GCOMP];  \
 
197
   DST[2] = VALUE[RCOMP]
 
198
#define FETCH_PIXEL(DST, SRC) \
 
199
   DST[RCOMP] = SRC[2];  \
 
200
   DST[GCOMP] = SRC[1];  \
 
201
   DST[BCOMP] = SRC[0];  \
 
202
   DST[ACOMP] = CHAN_MAX
 
203
 
 
204
#include "swrast/s_spantemp.h"
 
205
 
 
206
 
 
207
/* 32-bit BGRA */
 
208
#define NAME(PREFIX) PREFIX##_B8G8R8A8
 
209
#define RB_TYPE GLubyte
 
210
#define SPAN_VARS \
 
211
   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 
212
#define INIT_PIXEL_PTR(P, X, Y) \
 
213
   GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X) * 4
 
214
#define INC_PIXEL_PTR(P) P += 4
 
215
#define STORE_PIXEL(DST, X, Y, VALUE) \
 
216
   DST[0] = VALUE[BCOMP];  \
 
217
   DST[1] = VALUE[GCOMP];  \
 
218
   DST[2] = VALUE[RCOMP];  \
 
219
   DST[3] = VALUE[ACOMP]
 
220
#define FETCH_PIXEL(DST, SRC) \
 
221
   DST[RCOMP] = SRC[2];  \
 
222
   DST[GCOMP] = SRC[1];  \
 
223
   DST[BCOMP] = SRC[0];  \
 
224
   DST[ACOMP] = SRC[3]
 
225
 
 
226
#include "swrast/s_spantemp.h"
 
227
 
 
228
 
 
229
/* 16-bit BGR (XXX implement dithering someday) */
 
230
#define NAME(PREFIX) PREFIX##_B5G6R5
 
231
#define RB_TYPE GLubyte
 
232
#define SPAN_VARS \
 
233
   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 
234
#define INIT_PIXEL_PTR(P, X, Y) \
 
235
   GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
 
236
#define INC_PIXEL_PTR(P) P += 1
 
237
#define STORE_PIXEL(DST, X, Y, VALUE) \
 
238
   DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
 
239
#define FETCH_PIXEL(DST, SRC) \
 
240
   DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
 
241
   DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >>  5) & 0x3) ); \
 
242
   DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0])      ) & 0x7) ); \
 
243
   DST[ACOMP] = CHAN_MAX
 
244
 
 
245
#include "swrast/s_spantemp.h"
 
246
 
 
247
 
 
248
/* 15-bit BGR (XXX implement dithering someday) */
 
249
#define NAME(PREFIX) PREFIX##_B5G5R5
 
250
#define RB_TYPE GLubyte
 
251
#define SPAN_VARS \
 
252
   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 
253
#define INIT_PIXEL_PTR(P, X, Y) \
 
254
   GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (X) * 2)
 
255
#define INC_PIXEL_PTR(P) P += 1
 
256
#define STORE_PIXEL(DST, X, Y, VALUE) \
 
257
   DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
 
258
#define FETCH_PIXEL(DST, SRC) \
 
259
   DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
 
260
   DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >>  5) & 0x7) ); \
 
261
   DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0])      ) & 0x7) ); \
 
262
   DST[ACOMP] = CHAN_MAX
 
263
 
 
264
#include "swrast/s_spantemp.h"
 
265
 
 
266
 
 
267
/* 8-bit color index */
 
268
#define NAME(PREFIX) PREFIX##_CI8
 
269
#define CI_MODE
 
270
#define RB_TYPE GLubyte
 
271
#define SPAN_VARS \
 
272
   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 
273
#define INIT_PIXEL_PTR(P, X, Y) \
 
274
   GLubyte *P = frb->bottom - (Y) * frb->rowStride + (X)
 
275
#define INC_PIXEL_PTR(P) P += 1
 
276
#define STORE_PIXEL(DST, X, Y, VALUE) \
 
277
   *DST = VALUE[0]
 
278
#define FETCH_PIXEL(DST, SRC) \
 
279
   DST = SRC[0]
 
280
 
 
281
#include "swrast/s_spantemp.h"
 
282
 
 
283
 
 
284
 
 
285
 
 
286
/**********************************************************************/
 
287
/* Public API functions                                               */
 
288
/**********************************************************************/
 
289
 
 
290
 
 
291
const char *
 
292
glFBDevGetString( int str )
 
293
{
 
294
   switch (str) {
 
295
   case GLFBDEV_VENDOR:
 
296
      return "Mesa Project";
 
297
   case GLFBDEV_VERSION:
 
298
      return "1.0.1";
 
299
   default:
 
300
      return NULL;
 
301
   }
 
302
}
 
303
 
 
304
 
 
305
GLFBDevProc
 
306
glFBDevGetProcAddress( const char *procName )
 
307
{
 
308
   struct name_address {
 
309
      const char *name;
 
310
      const GLFBDevProc func;
 
311
   };
 
312
   static const struct name_address functions[] = {
 
313
      { "glFBDevGetString", (GLFBDevProc) glFBDevGetString },
 
314
      { "glFBDevGetProcAddress", (GLFBDevProc) glFBDevGetProcAddress },
 
315
      { "glFBDevCreateVisual", (GLFBDevProc) glFBDevCreateVisual },
 
316
      { "glFBDevDestroyVisual", (GLFBDevProc) glFBDevDestroyVisual },
 
317
      { "glFBDevGetVisualAttrib", (GLFBDevProc) glFBDevGetVisualAttrib },
 
318
      { "glFBDevCreateBuffer", (GLFBDevProc) glFBDevCreateBuffer },
 
319
      { "glFBDevDestroyBuffer", (GLFBDevProc) glFBDevDestroyBuffer },
 
320
      { "glFBDevGetBufferAttrib", (GLFBDevProc) glFBDevGetBufferAttrib },
 
321
      { "glFBDevGetCurrentDrawBuffer", (GLFBDevProc) glFBDevGetCurrentDrawBuffer },
 
322
      { "glFBDevGetCurrentReadBuffer", (GLFBDevProc) glFBDevGetCurrentReadBuffer },
 
323
      { "glFBDevSwapBuffers", (GLFBDevProc) glFBDevSwapBuffers },
 
324
      { "glFBDevCreateContext", (GLFBDevProc) glFBDevCreateContext },
 
325
      { "glFBDevDestroyContext", (GLFBDevProc) glFBDevDestroyContext },
 
326
      { "glFBDevGetContextAttrib", (GLFBDevProc) glFBDevGetContextAttrib },
 
327
      { "glFBDevGetCurrentContext", (GLFBDevProc) glFBDevGetCurrentContext },
 
328
      { "glFBDevMakeCurrent", (GLFBDevProc) glFBDevMakeCurrent },
 
329
      { NULL, NULL }
 
330
   };
 
331
   const struct name_address *entry;
 
332
   for (entry = functions; entry->name; entry++) {
 
333
      if (_mesa_strcmp(entry->name, procName) == 0) {
 
334
         return entry->func;
 
335
      }
 
336
   }
 
337
   return _glapi_get_proc_address(procName);
 
338
}
 
339
 
 
340
 
 
341
GLFBDevVisualPtr
 
342
glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
 
343
                     const struct fb_var_screeninfo *varInfo,
 
344
                     const int *attribs )
 
345
{
 
346
   GLFBDevVisualPtr vis;
 
347
   const int *attrib;
 
348
   GLboolean rgbFlag = GL_TRUE, dbFlag = GL_FALSE, stereoFlag = GL_FALSE;
 
349
   GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0;
 
350
   GLint indexBits = 0, depthBits = 0, stencilBits = 0;
 
351
   GLint accumRedBits = 0, accumGreenBits = 0;
 
352
   GLint accumBlueBits = 0, accumAlphaBits = 0;
 
353
   GLint numSamples = 0;
 
354
 
 
355
   ASSERT(fixInfo);
 
356
   ASSERT(varInfo);
 
357
 
 
358
   vis = CALLOC_STRUCT(GLFBDevVisualRec);
 
359
   if (!vis)
 
360
      return NULL;
 
361
 
 
362
   vis->fix = *fixInfo;  /* struct assignment */
 
363
   vis->var = *varInfo;  /* struct assignment */
 
364
 
 
365
   for (attrib = attribs; attrib && *attrib != GLFBDEV_NONE; attrib++) {
 
366
      switch (*attrib) {
 
367
      case GLFBDEV_DOUBLE_BUFFER:
 
368
         dbFlag = GL_TRUE;
 
369
         break;
 
370
      case GLFBDEV_COLOR_INDEX:
 
371
         rgbFlag = GL_FALSE;
 
372
         break;
 
373
      case GLFBDEV_DEPTH_SIZE:
 
374
         depthBits = attrib[1];
 
375
         attrib++;
 
376
         break;
 
377
      case GLFBDEV_STENCIL_SIZE:
 
378
         stencilBits = attrib[1];
 
379
         attrib++;
 
380
         break;
 
381
      case GLFBDEV_ACCUM_SIZE:
 
382
         accumRedBits = accumGreenBits = accumBlueBits = accumAlphaBits
 
383
            = attrib[1];
 
384
         attrib++;
 
385
         break;
 
386
      case GLFBDEV_LEVEL:
 
387
         /* ignored for now */
 
388
         break;
 
389
      case GLFBDEV_MULTISAMPLE:
 
390
         numSamples = attrib[1];
 
391
         attrib++;
 
392
         break;
 
393
      default:
 
394
         /* unexpected token */
 
395
         _mesa_free(vis);
 
396
         return NULL;
 
397
      }
 
398
   }
 
399
 
 
400
   if (rgbFlag) {
 
401
      redBits   = varInfo->red.length;
 
402
      greenBits = varInfo->green.length;
 
403
      blueBits  = varInfo->blue.length;
 
404
      alphaBits = varInfo->transp.length;
 
405
 
 
406
      if (fixInfo->visual == FB_VISUAL_TRUECOLOR ||
 
407
          fixInfo->visual == FB_VISUAL_DIRECTCOLOR) {
 
408
         if (varInfo->bits_per_pixel == 24
 
409
             && varInfo->red.offset == 16
 
410
             && varInfo->green.offset == 8
 
411
             && varInfo->blue.offset == 0) {
 
412
            vis->pixelFormat = PF_B8G8R8;
 
413
         }
 
414
         else if (varInfo->bits_per_pixel == 32
 
415
                  && varInfo->red.offset == 16
 
416
                  && varInfo->green.offset == 8
 
417
                  && varInfo->blue.offset == 0) {
 
418
            vis->pixelFormat = PF_B8G8R8A8;
 
419
         }
 
420
         else if (varInfo->bits_per_pixel == 16
 
421
                  && varInfo->red.offset == 11
 
422
                  && varInfo->green.offset == 5
 
423
                  && varInfo->blue.offset == 0) {
 
424
            vis->pixelFormat = PF_B5G6R5;
 
425
         }
 
426
         else if (varInfo->bits_per_pixel == 16
 
427
                  && varInfo->red.offset == 10
 
428
                  && varInfo->green.offset == 5
 
429
                  && varInfo->blue.offset == 0) {
 
430
            vis->pixelFormat = PF_B5G5R5;
 
431
         }
 
432
         else {
 
433
            _mesa_problem(NULL, "Unsupported fbdev RGB visual/bitdepth!\n");
 
434
            _mesa_free(vis);
 
435
            return NULL;
 
436
         }
 
437
      }
 
438
   }
 
439
   else {
 
440
      indexBits = varInfo->bits_per_pixel;
 
441
      if ((fixInfo->visual == FB_VISUAL_PSEUDOCOLOR ||
 
442
           fixInfo->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
 
443
          && varInfo->bits_per_pixel == 8) {
 
444
         vis->pixelFormat = PF_CI8;
 
445
      }
 
446
      else {
 
447
         _mesa_problem(NULL, "Unsupported fbdev CI visual/bitdepth!\n");
 
448
         _mesa_free(vis);
 
449
         return NULL;
 
450
      }
 
451
   }
 
452
 
 
453
   if (!_mesa_initialize_visual(&vis->glvisual, rgbFlag, dbFlag, stereoFlag,
 
454
                                redBits, greenBits, blueBits, alphaBits,
 
455
                                indexBits, depthBits, stencilBits,
 
456
                                accumRedBits, accumGreenBits,
 
457
                                accumBlueBits, accumAlphaBits,
 
458
                                numSamples)) {
 
459
      /* something was invalid */
 
460
      _mesa_free(vis);
 
461
      return NULL;
 
462
   }
 
463
 
 
464
   return vis;
 
465
}
 
466
 
 
467
 
 
468
void
 
469
glFBDevDestroyVisual( GLFBDevVisualPtr visual )
 
470
{
 
471
   if (visual)
 
472
      _mesa_free(visual);
 
473
}
 
474
 
 
475
 
 
476
int
 
477
glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual, int attrib)
 
478
{
 
479
   /* XXX unfinished */
 
480
   (void) visual;
 
481
   (void) attrib;
 
482
   return -1;
 
483
}
 
484
 
 
485
 
 
486
static void
 
487
delete_renderbuffer(struct gl_renderbuffer *rb)
 
488
{
 
489
   struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
 
490
   if (frb->mallocedBuffer) {
 
491
      _mesa_free(frb->Base.Data);
 
492
   }
 
493
   _mesa_free(frb);
 
494
}
 
495
 
 
496
 
 
497
static GLboolean
 
498
renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
 
499
                     GLenum internalFormat, GLuint width, GLuint height)
 
500
{
 
501
   /* no-op: the renderbuffer storage is allocated just once when it's
 
502
    * created.  Never resized or reallocated.
 
503
    */
 
504
   return GL_TRUE;
 
505
}
 
506
 
 
507
 
 
508
static struct GLFBDevRenderbufferRec *
 
509
new_glfbdev_renderbuffer(void *bufferStart, const GLFBDevVisualPtr visual)
 
510
{
 
511
   struct GLFBDevRenderbufferRec *rb = CALLOC_STRUCT(GLFBDevRenderbufferRec);
 
512
   if (rb) {
 
513
      GLuint name = 0;
 
514
      int pixelFormat = visual->pixelFormat;
 
515
 
 
516
      _mesa_init_renderbuffer(&rb->Base, name);
 
517
 
 
518
      rb->Base.Delete = delete_renderbuffer;
 
519
      rb->Base.AllocStorage = renderbuffer_storage;
 
520
 
 
521
      if (pixelFormat == PF_B8G8R8) {
 
522
         rb->Base.GetRow = get_row_B8G8R8;
 
523
         rb->Base.GetValues = get_values_B8G8R8;
 
524
         rb->Base.PutRow = put_row_B8G8R8;
 
525
         rb->Base.PutRowRGB = put_row_rgb_B8G8R8;
 
526
         rb->Base.PutMonoRow = put_mono_row_B8G8R8;
 
527
         rb->Base.PutValues = put_values_B8G8R8;
 
528
         rb->Base.PutMonoValues = put_mono_values_B8G8R8;
 
529
      }
 
530
      else if (pixelFormat == PF_B8G8R8A8) {
 
531
         rb->Base.GetRow = get_row_B8G8R8A8;
 
532
         rb->Base.GetValues = get_values_B8G8R8A8;
 
533
         rb->Base.PutRow = put_row_B8G8R8A8;
 
534
         rb->Base.PutRowRGB = put_row_rgb_B8G8R8A8;
 
535
         rb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
 
536
         rb->Base.PutValues = put_values_B8G8R8A8;
 
537
         rb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
 
538
      }
 
539
      else if (pixelFormat == PF_B5G6R5) {
 
540
         rb->Base.GetRow = get_row_B5G6R5;
 
541
         rb->Base.GetValues = get_values_B5G6R5;
 
542
         rb->Base.PutRow = put_row_B5G6R5;
 
543
         rb->Base.PutRowRGB = put_row_rgb_B5G6R5;
 
544
         rb->Base.PutMonoRow = put_mono_row_B5G6R5;
 
545
         rb->Base.PutValues = put_values_B5G6R5;
 
546
         rb->Base.PutMonoValues = put_mono_values_B5G6R5;
 
547
      }
 
548
      else if (pixelFormat == PF_B5G5R5) {
 
549
         rb->Base.GetRow = get_row_B5G5R5;
 
550
         rb->Base.GetValues = get_values_B5G5R5;
 
551
         rb->Base.PutRow = put_row_B5G5R5;
 
552
         rb->Base.PutRowRGB = put_row_rgb_B5G5R5;
 
553
         rb->Base.PutMonoRow = put_mono_row_B5G5R5;
 
554
         rb->Base.PutValues = put_values_B5G5R5;
 
555
         rb->Base.PutMonoValues = put_mono_values_B5G5R5;
 
556
      }
 
557
      else if (pixelFormat == PF_CI8) {
 
558
         rb->Base.GetRow = get_row_CI8;
 
559
         rb->Base.GetValues = get_values_CI8;
 
560
         rb->Base.PutRow = put_row_CI8;
 
561
         rb->Base.PutMonoRow = put_mono_row_CI8;
 
562
         rb->Base.PutValues = put_values_CI8;
 
563
         rb->Base.PutMonoValues = put_mono_values_CI8;
 
564
      }
 
565
 
 
566
      if (pixelFormat == PF_CI8) {
 
567
         rb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
 
568
         rb->Base._BaseFormat = GL_COLOR_INDEX;
 
569
      }
 
570
      else {
 
571
         rb->Base.InternalFormat = GL_RGBA;
 
572
         rb->Base._BaseFormat = GL_RGBA;
 
573
      }
 
574
      rb->Base.DataType = GL_UNSIGNED_BYTE;
 
575
      rb->Base.Data = bufferStart;
 
576
 
 
577
      rb->rowStride = visual->var.xres_virtual * visual->var.bits_per_pixel / 8;
 
578
      rb->bottom = (GLubyte *) bufferStart
 
579
                 + (visual->var.yres - 1) * rb->rowStride;
 
580
 
 
581
      rb->Base.Width = visual->var.xres;
 
582
      rb->Base.Height = visual->var.yres;
 
583
 
 
584
      rb->Base.RedBits = visual->var.red.length;
 
585
      rb->Base.GreenBits = visual->var.green.length;
 
586
      rb->Base.BlueBits = visual->var.blue.length;
 
587
      rb->Base.AlphaBits = visual->var.transp.length;
 
588
 
 
589
      rb->Base.InternalFormat = pixelFormat;
 
590
   }
 
591
   return rb;
 
592
}
 
593
 
 
594
GLFBDevBufferPtr
 
595
glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
 
596
                     const struct fb_var_screeninfo *varInfo,
 
597
                     const GLFBDevVisualPtr visual,
 
598
                     void *frontBuffer, void *backBuffer, size_t size )
 
599
{
 
600
   struct GLFBDevRenderbufferRec *frontrb, *backrb;
 
601
   GLFBDevBufferPtr buf;
 
602
 
 
603
   ASSERT(visual);
 
604
   ASSERT(frontBuffer);
 
605
   ASSERT(size > 0);
 
606
 
 
607
   /* this is to update the visual if there was a resize and the
 
608
      buffer is created again */
 
609
   visual->var = *varInfo;
 
610
   visual->fix = *fixInfo;
 
611
 
 
612
   if (visual->fix.visual != fixInfo->visual ||
 
613
       visual->fix.type != fixInfo->type ||
 
614
       visual->var.bits_per_pixel != varInfo->bits_per_pixel ||
 
615
       visual->var.grayscale != varInfo->grayscale ||
 
616
       visual->var.red.offset != varInfo->red.offset ||
 
617
       visual->var.green.offset != varInfo->green.offset ||
 
618
       visual->var.blue.offset != varInfo->blue.offset ||
 
619
       visual->var.transp.offset != varInfo->transp.offset) {
 
620
      /* visual mismatch! */
 
621
      return NULL;
 
622
   }
 
623
 
 
624
   buf = CALLOC_STRUCT(GLFBDevBufferRec);
 
625
   if (!buf)
 
626
      return NULL;
 
627
 
 
628
   /* basic framebuffer setup */
 
629
   _mesa_initialize_framebuffer(&buf->glframebuffer, &visual->glvisual);
 
630
   /* add front renderbuffer */
 
631
   frontrb = new_glfbdev_renderbuffer(frontBuffer, visual);
 
632
   _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT,
 
633
                          &frontrb->Base);
 
634
   /* add back renderbuffer */
 
635
   if (visual->glvisual.doubleBufferMode) {
 
636
      const int malloced = !backBuffer;
 
637
      if (malloced) {
 
638
         /* malloc a back buffer */
 
639
         backBuffer = _mesa_malloc(size);
 
640
         if (!backBuffer) {
 
641
            _mesa_free_framebuffer_data(&buf->glframebuffer);
 
642
            _mesa_free(buf);
 
643
            return NULL;
 
644
         }
 
645
      }
 
646
 
 
647
      backrb = new_glfbdev_renderbuffer(backBuffer, visual);
 
648
      if (!backrb) {
 
649
         /* out of mem */
 
650
         return NULL;
 
651
      }
 
652
      backrb->mallocedBuffer = malloced;
 
653
 
 
654
      _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT,
 
655
                             &backrb->Base);
 
656
   }
 
657
   /* add software renderbuffers */
 
658
   _mesa_add_soft_renderbuffers(&buf->glframebuffer,
 
659
                                GL_FALSE, /* color */
 
660
                                visual->glvisual.haveDepthBuffer,
 
661
                                visual->glvisual.haveStencilBuffer,
 
662
                                visual->glvisual.haveAccumBuffer,
 
663
                                GL_FALSE, /* alpha */
 
664
                                GL_FALSE /* aux bufs */);
 
665
 
 
666
   buf->fix = *fixInfo;   /* struct assignment */
 
667
   buf->var = *varInfo;   /* struct assignment */
 
668
   buf->visual = visual;  /* ptr assignment */
 
669
   buf->size = size;
 
670
   buf->bytesPerPixel = visual->var.bits_per_pixel / 8;
 
671
 
 
672
   return buf;
 
673
}
 
674
 
 
675
 
 
676
void
 
677
glFBDevDestroyBuffer( GLFBDevBufferPtr buffer )
 
678
{
 
679
   if (buffer) {
 
680
      /* check if destroying the current buffer */
 
681
      GLFBDevBufferPtr curDraw = glFBDevGetCurrentDrawBuffer();
 
682
      GLFBDevBufferPtr curRead = glFBDevGetCurrentReadBuffer();
 
683
      if (buffer == curDraw || buffer == curRead) {
 
684
         glFBDevMakeCurrent( NULL, NULL, NULL);
 
685
      }
 
686
      {
 
687
         struct gl_framebuffer *fb = &buffer->glframebuffer;
 
688
         _mesa_unreference_framebuffer(&fb);
 
689
      }
 
690
   }
 
691
}
 
692
 
 
693
 
 
694
int
 
695
glFBDevGetBufferAttrib( const GLFBDevBufferPtr buffer, int attrib)
 
696
{
 
697
   (void) buffer;
 
698
   (void) attrib;
 
699
   return -1;
 
700
}
 
701
 
 
702
 
 
703
GLFBDevBufferPtr
 
704
glFBDevGetCurrentDrawBuffer( void )
 
705
{
 
706
   GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
 
707
   if (fbdevctx)
 
708
      return fbdevctx->drawBuffer;
 
709
   else
 
710
      return NULL;
 
711
}
 
712
 
 
713
 
 
714
GLFBDevBufferPtr
 
715
glFBDevGetCurrentReadBuffer( void )
 
716
{
 
717
   GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
 
718
   if (fbdevctx)
 
719
      return fbdevctx->readBuffer;
 
720
   else
 
721
      return NULL;
 
722
}
 
723
 
 
724
 
 
725
void
 
726
glFBDevSwapBuffers( GLFBDevBufferPtr buffer )
 
727
{
 
728
   GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
 
729
   struct GLFBDevRenderbufferRec *frontrb = (struct GLFBDevRenderbufferRec *)
 
730
      buffer->glframebuffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
 
731
   struct GLFBDevRenderbufferRec *backrb = (struct GLFBDevRenderbufferRec *)
 
732
      buffer->glframebuffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
 
733
 
 
734
   if (!buffer || !buffer->visual->glvisual.doubleBufferMode)
 
735
      return;
 
736
 
 
737
   /* check if swapping currently bound buffer */
 
738
   if (fbdevctx->drawBuffer == buffer) {
 
739
      /* flush pending rendering */
 
740
      _mesa_notifySwapBuffers(&fbdevctx->glcontext);
 
741
   }
 
742
 
 
743
   ASSERT(frontrb->Base.Data);
 
744
   ASSERT(backrb->Base.Data);
 
745
   _mesa_memcpy(frontrb->Base.Data, backrb->Base.Data, buffer->size);
 
746
}
 
747
 
 
748
 
 
749
GLFBDevContextPtr
 
750
glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share )
 
751
{
 
752
   GLFBDevContextPtr ctx;
 
753
   GLcontext *glctx;
 
754
   struct dd_function_table functions;
 
755
 
 
756
   ASSERT(visual);
 
757
 
 
758
   ctx = CALLOC_STRUCT(GLFBDevContextRec);
 
759
   if (!ctx)
 
760
      return NULL;
 
761
 
 
762
   /* build table of device driver functions */
 
763
   _mesa_init_driver_functions(&functions);
 
764
   functions.GetString = get_string;
 
765
   functions.UpdateState = update_state;
 
766
   functions.GetBufferSize = get_buffer_size;
 
767
   functions.Viewport = viewport;
 
768
 
 
769
   if (!_mesa_initialize_context(&ctx->glcontext, &visual->glvisual,
 
770
                                 share ? &share->glcontext : NULL,
 
771
                                 &functions, (void *) ctx)) {
 
772
      _mesa_free(ctx);
 
773
      return NULL;
 
774
   }
 
775
 
 
776
   ctx->visual = visual;
 
777
 
 
778
   /* Create module contexts */
 
779
   glctx = (GLcontext *) &ctx->glcontext;
 
780
   _swrast_CreateContext( glctx );
 
781
   _vbo_CreateContext( glctx );
 
782
   _tnl_CreateContext( glctx );
 
783
   _swsetup_CreateContext( glctx );
 
784
   _swsetup_Wakeup( glctx );
 
785
 
 
786
   /* use default TCL pipeline */
 
787
   {
 
788
      TNLcontext *tnl = TNL_CONTEXT(glctx);
 
789
      tnl->Driver.RunPipeline = _tnl_run_pipeline;
 
790
   }
 
791
 
 
792
   _mesa_enable_sw_extensions(glctx);
 
793
   _mesa_enable_1_3_extensions(glctx);
 
794
   _mesa_enable_1_4_extensions(glctx);
 
795
   _mesa_enable_1_5_extensions(glctx);
 
796
   _mesa_enable_2_0_extensions(glctx);
 
797
   _mesa_enable_2_1_extensions(glctx);
 
798
 
 
799
   return ctx;
 
800
}
 
801
 
 
802
 
 
803
void
 
804
glFBDevDestroyContext( GLFBDevContextPtr context )
 
805
{
 
806
   GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
 
807
 
 
808
   if (context) {
 
809
      GLcontext *mesaCtx = &context->glcontext;
 
810
 
 
811
      _swsetup_DestroyContext( mesaCtx );
 
812
      _swrast_DestroyContext( mesaCtx );
 
813
      _tnl_DestroyContext( mesaCtx );
 
814
      _vbo_DestroyContext( mesaCtx );
 
815
 
 
816
      if (fbdevctx == context) {
 
817
         /* destroying current context */
 
818
         _mesa_make_current(NULL, NULL, NULL);
 
819
      }
 
820
      _mesa_free_context_data(&context->glcontext);
 
821
      _mesa_free(context);
 
822
   }
 
823
}
 
824
 
 
825
 
 
826
int
 
827
glFBDevGetContextAttrib( const GLFBDevContextPtr context, int attrib)
 
828
{
 
829
   (void) context;
 
830
   (void) attrib;
 
831
   return -1;
 
832
}
 
833
 
 
834
 
 
835
GLFBDevContextPtr
 
836
glFBDevGetCurrentContext( void )
 
837
{
 
838
   GET_CURRENT_CONTEXT(ctx);
 
839
   return (GLFBDevContextPtr) ctx;
 
840
}
 
841
 
 
842
 
 
843
int
 
844
glFBDevMakeCurrent( GLFBDevContextPtr context,
 
845
                    GLFBDevBufferPtr drawBuffer,
 
846
                    GLFBDevBufferPtr readBuffer )
 
847
{
 
848
   if (context && drawBuffer && readBuffer) {
 
849
      /* Make sure the context's visual and the buffers' visuals match.
 
850
       * XXX we might do this by comparing specific fields like bits_per_pixel,
 
851
       * visual, etc. in the future.
 
852
       */
 
853
      if (context->visual != drawBuffer->visual ||
 
854
          context->visual != readBuffer->visual) {
 
855
         return 0;
 
856
      }
 
857
      _mesa_make_current( &context->glcontext,
 
858
                          &drawBuffer->glframebuffer,
 
859
                          &readBuffer->glframebuffer );
 
860
      context->drawBuffer = drawBuffer;
 
861
      context->readBuffer = readBuffer;
 
862
      context->curBuffer = drawBuffer;
 
863
   }
 
864
   else {
 
865
      /* unbind */
 
866
      _mesa_make_current( NULL, NULL, NULL );
 
867
   }
 
868
 
 
869
   return 1;
 
870
}
 
871
 
 
872
#endif /* USE_GLFBDEV_DRIVER */