Subversion Repositories Kolibri OS

Rev

Rev 4401 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4401 Rev 5373
1
/*
1
/*
2
 * Mesa 3-D graphics library
2
 * Mesa 3-D graphics library
3
 *
3
 *
4
 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
4
 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
12
 *
13
 * The above copyright notice and this permission notice shall be included
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
14
 * in all copies or substantial portions of the Software.
15
 *
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 * OTHER DEALINGS IN THE SOFTWARE.
22
 * OTHER DEALINGS IN THE SOFTWARE.
23
 */
23
 */
24
 
24
 
25
 
25
 
26
/*
26
/*
27
 * Off-Screen Mesa rendering / Rendering into client memory space
27
 * Off-Screen Mesa rendering / Rendering into client memory space
28
 *
28
 *
29
 * Note on thread safety:  this driver is thread safe.  All
29
 * Note on thread safety:  this driver is thread safe.  All
30
 * functions are reentrant.  The notion of current context is
30
 * functions are reentrant.  The notion of current context is
31
 * managed by the core _mesa_make_current() and _mesa_get_current_context()
31
 * managed by the core _mesa_make_current() and _mesa_get_current_context()
32
 * functions.  Those functions are thread-safe.
32
 * functions.  Those functions are thread-safe.
33
 */
33
 */
34
 
34
 
35
 
35
 
36
#include "main/glheader.h"
36
#include "main/glheader.h"
37
#include "GL/osmesa.h"
37
#include "GL/osmesa.h"
38
#include "main/api_exec.h"
38
#include "main/api_exec.h"
39
#include "main/context.h"
39
#include "main/context.h"
40
#include "main/extensions.h"
40
#include "main/extensions.h"
41
#include "main/formats.h"
41
#include "main/formats.h"
42
#include "main/framebuffer.h"
42
#include "main/framebuffer.h"
43
#include "main/imports.h"
43
#include "main/imports.h"
44
#include "main/macros.h"
44
#include "main/macros.h"
45
#include "main/mipmap.h"
45
#include "main/mipmap.h"
46
#include "main/mtypes.h"
46
#include "main/mtypes.h"
47
#include "main/renderbuffer.h"
47
#include "main/renderbuffer.h"
48
#include "main/version.h"
48
#include "main/version.h"
49
#include "main/vtxfmt.h"
49
#include "main/vtxfmt.h"
50
#include "swrast/swrast.h"
50
#include "swrast/swrast.h"
51
#include "swrast_setup/swrast_setup.h"
51
#include "swrast_setup/swrast_setup.h"
52
#include "swrast/s_context.h"
52
#include "swrast/s_context.h"
53
#include "swrast/s_lines.h"
53
#include "swrast/s_lines.h"
54
#include "swrast/s_renderbuffer.h"
54
#include "swrast/s_renderbuffer.h"
55
#include "swrast/s_triangle.h"
55
#include "swrast/s_triangle.h"
56
#include "tnl/tnl.h"
56
#include "tnl/tnl.h"
57
#include "tnl/t_context.h"
57
#include "tnl/t_context.h"
58
#include "tnl/t_pipeline.h"
58
#include "tnl/t_pipeline.h"
59
#include "drivers/common/driverfuncs.h"
59
#include "drivers/common/driverfuncs.h"
60
#include "drivers/common/meta.h"
60
#include "drivers/common/meta.h"
61
#include "vbo/vbo.h"
61
#include "vbo/vbo.h"
62
 
62
 
63
 
63
 
64
#define OSMESA_RENDERBUFFER_CLASS 0x053
64
#define OSMESA_RENDERBUFFER_CLASS 0x053
65
 
65
 
66
 
66
 
67
/**
67
/**
68
 * OSMesa rendering context, derived from core Mesa struct gl_context.
68
 * OSMesa rendering context, derived from core Mesa struct gl_context.
69
 */
69
 */
70
struct osmesa_context
70
struct osmesa_context
71
{
71
{
72
   struct gl_context mesa;		/*< Base class - this must be first */
72
   struct gl_context mesa;		/*< Base class - this must be first */
73
   struct gl_config *gl_visual;		/*< Describes the buffers */
73
   struct gl_config *gl_visual;		/*< Describes the buffers */
74
   struct swrast_renderbuffer *srb;     /*< The user's colorbuffer */
74
   struct swrast_renderbuffer *srb;     /*< The user's colorbuffer */
75
   struct gl_framebuffer *gl_buffer;	/*< The framebuffer, containing user's rb */
75
   struct gl_framebuffer *gl_buffer;	/*< The framebuffer, containing user's rb */
76
   GLenum format;		/*< User-specified context format */
76
   GLenum format;		/*< User-specified context format */
77
   GLint userRowLength;		/*< user-specified number of pixels per row */
77
   GLint userRowLength;		/*< user-specified number of pixels per row */
78
   GLint rInd, gInd, bInd, aInd;/*< index offsets for RGBA formats */
78
   GLint rInd, gInd, bInd, aInd;/*< index offsets for RGBA formats */
79
   GLvoid *rowaddr[SWRAST_MAX_HEIGHT];	/*< address of first pixel in each image row */
79
   GLvoid *rowaddr[SWRAST_MAX_HEIGHT];	/*< address of first pixel in each image row */
80
   GLboolean yup;		/*< TRUE  -> Y increases upward */
80
   GLboolean yup;		/*< TRUE  -> Y increases upward */
81
				/*< FALSE -> Y increases downward */
81
				/*< FALSE -> Y increases downward */
82
   GLenum DataType;
82
   GLenum DataType;
83
};
83
};
84
 
84
 
85
 
85
 
86
static INLINE OSMesaContext
86
static INLINE OSMesaContext
87
OSMESA_CONTEXT(struct gl_context *ctx)
87
OSMESA_CONTEXT(struct gl_context *ctx)
88
{
88
{
89
   /* Just cast, since we're using structure containment */
89
   /* Just cast, since we're using structure containment */
90
   return (OSMesaContext) ctx;
90
   return (OSMesaContext) ctx;
91
}
91
}
92
 
92
 
93
 
93
 
94
/**********************************************************************/
94
/**********************************************************************/
95
/*** Private Device Driver Functions                                ***/
95
/*** Private Device Driver Functions                                ***/
96
/**********************************************************************/
96
/**********************************************************************/
97
 
97
 
98
 
98
 
99
static const GLubyte *
99
static const GLubyte *
100
get_string( struct gl_context *ctx, GLenum name )
100
get_string( struct gl_context *ctx, GLenum name )
101
{
101
{
102
   (void) ctx;
102
   (void) ctx;
103
   switch (name) {
103
   switch (name) {
104
      case GL_RENDERER:
104
      case GL_RENDERER:
105
#if CHAN_BITS == 32
105
#if CHAN_BITS == 32
106
         return (const GLubyte *) "Mesa OffScreen32";
106
         return (const GLubyte *) "Mesa OffScreen32";
107
#elif CHAN_BITS == 16
107
#elif CHAN_BITS == 16
108
         return (const GLubyte *) "Mesa OffScreen16";
108
         return (const GLubyte *) "Mesa OffScreen16";
109
#else
109
#else
110
         return (const GLubyte *) "Mesa OffScreen";
110
         return (const GLubyte *) "Mesa OffScreen";
111
#endif
111
#endif
112
      default:
112
      default:
113
         return NULL;
113
         return NULL;
114
   }
114
   }
115
}
115
}
116
 
116
 
117
 
117
 
118
static void
118
static void
119
osmesa_update_state( struct gl_context *ctx, GLuint new_state )
119
osmesa_update_state( struct gl_context *ctx, GLuint new_state )
120
{
120
{
121
   /* easy - just propogate */
121
   /* easy - just propogate */
122
   _swrast_InvalidateState( ctx, new_state );
122
   _swrast_InvalidateState( ctx, new_state );
123
   _swsetup_InvalidateState( ctx, new_state );
123
   _swsetup_InvalidateState( ctx, new_state );
124
   _tnl_InvalidateState( ctx, new_state );
124
   _tnl_InvalidateState( ctx, new_state );
125
   _vbo_InvalidateState( ctx, new_state );
125
   _vbo_InvalidateState( ctx, new_state );
126
}
126
}
127
 
127
 
128
 
128
 
129
 
129
 
130
/**
130
/**
131
 * Macros for optimized line/triangle rendering.
131
 * Macros for optimized line/triangle rendering.
132
 * Only for 8-bit channel, RGBA, BGRA, ARGB formats.
132
 * Only for 8-bit channel, RGBA, BGRA, ARGB formats.
133
 */
133
 */
134
 
134
 
135
#define PACK_RGBA(DST, R, G, B, A)	\
135
#define PACK_RGBA(DST, R, G, B, A)	\
136
do {					\
136
do {					\
137
   (DST)[osmesa->rInd] = R;		\
137
   (DST)[osmesa->rInd] = R;		\
138
   (DST)[osmesa->gInd] = G;		\
138
   (DST)[osmesa->gInd] = G;		\
139
   (DST)[osmesa->bInd] = B;		\
139
   (DST)[osmesa->bInd] = B;		\
140
   (DST)[osmesa->aInd] = A;		\
140
   (DST)[osmesa->aInd] = A;		\
141
} while (0)
141
} while (0)
142
 
142
 
143
#define PIXELADDR4(X,Y)  ((GLchan *) osmesa->rowaddr[Y] + 4 * (X))
143
#define PIXELADDR4(X,Y)  ((GLchan *) osmesa->rowaddr[Y] + 4 * (X))
144
 
144
 
145
 
145
 
146
/**
146
/**
147
 * Draw a flat-shaded, RGB line into an osmesa buffer.
147
 * Draw a flat-shaded, RGB line into an osmesa buffer.
148
 */
148
 */
149
#define NAME flat_rgba_line
149
#define NAME flat_rgba_line
150
#define CLIP_HACK 1
150
#define CLIP_HACK 1
151
#define SETUP_CODE						\
151
#define SETUP_CODE						\
152
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);		\
152
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);		\
153
   const GLchan *color = vert1->color;
153
   const GLchan *color = vert1->color;
154
 
154
 
155
#define PLOT(X, Y)						\
155
#define PLOT(X, Y)						\
156
do {								\
156
do {								\
157
   GLchan *p = PIXELADDR4(X, Y);				\
157
   GLchan *p = PIXELADDR4(X, Y);				\
158
   PACK_RGBA(p, color[0], color[1], color[2], color[3]);	\
158
   PACK_RGBA(p, color[0], color[1], color[2], color[3]);	\
159
} while (0)
159
} while (0)
160
 
160
 
161
#include "swrast/s_linetemp.h"
161
#include "swrast/s_linetemp.h"
162
 
162
 
163
 
163
 
164
 
164
 
165
/**
165
/**
166
 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
166
 * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer.
167
 */
167
 */
168
#define NAME flat_rgba_z_line
168
#define NAME flat_rgba_z_line
169
#define CLIP_HACK 1
169
#define CLIP_HACK 1
170
#define INTERP_Z 1
170
#define INTERP_Z 1
171
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
171
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
172
#define SETUP_CODE					\
172
#define SETUP_CODE					\
173
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);	\
173
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);	\
174
   const GLchan *color = vert1->color;
174
   const GLchan *color = vert1->color;
175
 
175
 
176
#define PLOT(X, Y)					\
176
#define PLOT(X, Y)					\
177
do {							\
177
do {							\
178
   if (Z < *zPtr) {					\
178
   if (Z < *zPtr) {					\
179
      GLchan *p = PIXELADDR4(X, Y);			\
179
      GLchan *p = PIXELADDR4(X, Y);			\
180
      PACK_RGBA(p, color[RCOMP], color[GCOMP],		\
180
      PACK_RGBA(p, color[RCOMP], color[GCOMP],		\
181
                   color[BCOMP], color[ACOMP]);		\
181
                   color[BCOMP], color[ACOMP]);		\
182
      *zPtr = Z;					\
182
      *zPtr = Z;					\
183
   }							\
183
   }							\
184
} while (0)
184
} while (0)
185
 
185
 
186
#include "swrast/s_linetemp.h"
186
#include "swrast/s_linetemp.h"
187
 
187
 
188
 
188
 
189
 
189
 
190
/**
190
/**
191
 * Analyze context state to see if we can provide a fast line drawing
191
 * Analyze context state to see if we can provide a fast line drawing
192
 * function.  Otherwise, return NULL.
192
 * function.  Otherwise, return NULL.
193
 */
193
 */
194
static swrast_line_func
194
static swrast_line_func
195
osmesa_choose_line_function( struct gl_context *ctx )
195
osmesa_choose_line_function( struct gl_context *ctx )
196
{
196
{
197
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
197
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
198
   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
198
   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
199
 
199
 
200
   if (ctx->DrawBuffer &&
200
   if (ctx->DrawBuffer &&
201
       ctx->DrawBuffer->Visual.redBits == 32) {
201
       ctx->DrawBuffer->Visual.redBits == 32) {
202
      /* the special-case line functions in this file don't work
202
      /* the special-case line functions in this file don't work
203
       * for float color channels.
203
       * for float color channels.
204
       */
204
       */
205
      return NULL;
205
      return NULL;
206
   }
206
   }
207
 
207
 
208
   if (ctx->RenderMode != GL_RENDER)      return NULL;
208
   if (ctx->RenderMode != GL_RENDER)      return NULL;
209
   if (ctx->Line.SmoothFlag)              return NULL;
209
   if (ctx->Line.SmoothFlag)              return NULL;
210
   if (ctx->Texture._EnabledUnits)        return NULL;
210
   if (ctx->Texture._EnabledUnits)        return NULL;
211
   if (ctx->Light.ShadeModel != GL_FLAT)  return NULL;
211
   if (ctx->Light.ShadeModel != GL_FLAT)  return NULL;
212
   if (ctx->Line.Width != 1.0F)           return NULL;
212
   if (ctx->Line.Width != 1.0F)           return NULL;
213
   if (ctx->Line.StippleFlag)             return NULL;
213
   if (ctx->Line.StippleFlag)             return NULL;
214
   if (ctx->Line.SmoothFlag)              return NULL;
214
   if (ctx->Line.SmoothFlag)              return NULL;
215
   if (osmesa->format != OSMESA_RGBA &&
215
   if (osmesa->format != OSMESA_RGBA &&
216
       osmesa->format != OSMESA_BGRA &&
216
       osmesa->format != OSMESA_BGRA &&
217
       osmesa->format != OSMESA_ARGB)     return NULL;
217
       osmesa->format != OSMESA_ARGB)     return NULL;
218
 
218
 
219
   if (swrast->_RasterMask==DEPTH_BIT
219
   if (swrast->_RasterMask==DEPTH_BIT
220
       && ctx->Depth.Func==GL_LESS
220
       && ctx->Depth.Func==GL_LESS
221
       && ctx->Depth.Mask==GL_TRUE
221
       && ctx->Depth.Mask==GL_TRUE
222
       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
222
       && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
223
      return (swrast_line_func) flat_rgba_z_line;
223
      return (swrast_line_func) flat_rgba_z_line;
224
   }
224
   }
225
 
225
 
226
   if (swrast->_RasterMask == 0) {
226
   if (swrast->_RasterMask == 0) {
227
      return (swrast_line_func) flat_rgba_line;
227
      return (swrast_line_func) flat_rgba_line;
228
   }
228
   }
229
 
229
 
230
   return (swrast_line_func) NULL;
230
   return (swrast_line_func) NULL;
231
}
231
}
232
 
232
 
233
 
233
 
234
/**********************************************************************/
234
/**********************************************************************/
235
/*****                 Optimized triangle rendering               *****/
235
/*****                 Optimized triangle rendering               *****/
236
/**********************************************************************/
236
/**********************************************************************/
237
 
237
 
238
 
238
 
239
/*
239
/*
240
 * Smooth-shaded, z-less triangle, RGBA color.
240
 * Smooth-shaded, z-less triangle, RGBA color.
241
 */
241
 */
242
#define NAME smooth_rgba_z_triangle
242
#define NAME smooth_rgba_z_triangle
243
#define INTERP_Z 1
243
#define INTERP_Z 1
244
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
244
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
245
#define INTERP_RGB 1
245
#define INTERP_RGB 1
246
#define INTERP_ALPHA 1
246
#define INTERP_ALPHA 1
247
#define SETUP_CODE \
247
#define SETUP_CODE \
248
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
248
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
249
#define RENDER_SPAN( span ) {					\
249
#define RENDER_SPAN( span ) {					\
250
   GLuint i;							\
250
   GLuint i;							\
251
   GLchan *img = PIXELADDR4(span.x, span.y); 			\
251
   GLchan *img = PIXELADDR4(span.x, span.y); 			\
252
   for (i = 0; i < span.end; i++, img += 4) {			\
252
   for (i = 0; i < span.end; i++, img += 4) {			\
253
      const GLuint z = FixedToDepth(span.z);			\
253
      const GLuint z = FixedToDepth(span.z);			\
254
      if (z < zRow[i]) {					\
254
      if (z < zRow[i]) {					\
255
         PACK_RGBA(img, FixedToChan(span.red),			\
255
         PACK_RGBA(img, FixedToChan(span.red),			\
256
            FixedToChan(span.green), FixedToChan(span.blue),	\
256
            FixedToChan(span.green), FixedToChan(span.blue),	\
257
            FixedToChan(span.alpha));				\
257
            FixedToChan(span.alpha));				\
258
         zRow[i] = z;						\
258
         zRow[i] = z;						\
259
      }								\
259
      }								\
260
      span.red += span.redStep;					\
260
      span.red += span.redStep;					\
261
      span.green += span.greenStep;				\
261
      span.green += span.greenStep;				\
262
      span.blue += span.blueStep;				\
262
      span.blue += span.blueStep;				\
263
      span.alpha += span.alphaStep;				\
263
      span.alpha += span.alphaStep;				\
264
      span.z += span.zStep;					\
264
      span.z += span.zStep;					\
265
   }                                                            \
265
   }                                                            \
266
}
266
}
267
#include "swrast/s_tritemp.h"
267
#include "swrast/s_tritemp.h"
268
 
268
 
269
 
269
 
270
 
270
 
271
/*
271
/*
272
 * Flat-shaded, z-less triangle, RGBA color.
272
 * Flat-shaded, z-less triangle, RGBA color.
273
 */
273
 */
274
#define NAME flat_rgba_z_triangle
274
#define NAME flat_rgba_z_triangle
275
#define INTERP_Z 1
275
#define INTERP_Z 1
276
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
276
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
277
#define SETUP_CODE						\
277
#define SETUP_CODE						\
278
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);		\
278
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);		\
279
   GLuint pixel;						\
279
   GLuint pixel;						\
280
   PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1],	\
280
   PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1],	\
281
                                v2->color[2], v2->color[3]);
281
                                v2->color[2], v2->color[3]);
282
 
282
 
283
#define RENDER_SPAN( span ) {				\
283
#define RENDER_SPAN( span ) {				\
284
   GLuint i;						\
284
   GLuint i;						\
285
   GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y);	\
285
   GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y);	\
286
   for (i = 0; i < span.end; i++) {			\
286
   for (i = 0; i < span.end; i++) {			\
287
      const GLuint z = FixedToDepth(span.z);		\
287
      const GLuint z = FixedToDepth(span.z);		\
288
      if (z < zRow[i]) {				\
288
      if (z < zRow[i]) {				\
289
         img[i] = pixel;				\
289
         img[i] = pixel;				\
290
         zRow[i] = z;					\
290
         zRow[i] = z;					\
291
      }							\
291
      }							\
292
      span.z += span.zStep;				\
292
      span.z += span.zStep;				\
293
   }                                                    \
293
   }                                                    \
294
}
294
}
295
 
295
 
296
#include "swrast/s_tritemp.h"
296
#include "swrast/s_tritemp.h"
297
 
297
 
298
 
298
 
299
 
299
 
300
/**
300
/**
301
 * Return pointer to an optimized triangle function if possible.
301
 * Return pointer to an optimized triangle function if possible.
302
 */
302
 */
303
static swrast_tri_func
303
static swrast_tri_func
304
osmesa_choose_triangle_function( struct gl_context *ctx )
304
osmesa_choose_triangle_function( struct gl_context *ctx )
305
{
305
{
306
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
306
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
307
   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
307
   const SWcontext *swrast = SWRAST_CONTEXT(ctx);
308
 
308
 
309
   if (ctx->DrawBuffer &&
309
   if (ctx->DrawBuffer &&
310
       ctx->DrawBuffer->Visual.redBits == 32) {
310
       ctx->DrawBuffer->Visual.redBits == 32) {
311
      /* the special-case triangle functions in this file don't work
311
      /* the special-case triangle functions in this file don't work
312
       * for float color channels.
312
       * for float color channels.
313
       */
313
       */
314
      return (swrast_tri_func) NULL;
314
      return (swrast_tri_func) NULL;
315
   }
315
   }
316
 
316
 
317
   if (ctx->RenderMode != GL_RENDER)    return (swrast_tri_func) NULL;
317
   if (ctx->RenderMode != GL_RENDER)    return (swrast_tri_func) NULL;
318
   if (ctx->Polygon.SmoothFlag)         return (swrast_tri_func) NULL;
318
   if (ctx->Polygon.SmoothFlag)         return (swrast_tri_func) NULL;
319
   if (ctx->Polygon.StippleFlag)        return (swrast_tri_func) NULL;
319
   if (ctx->Polygon.StippleFlag)        return (swrast_tri_func) NULL;
320
   if (ctx->Texture._EnabledUnits)      return (swrast_tri_func) NULL;
320
   if (ctx->Texture._EnabledUnits)      return (swrast_tri_func) NULL;
321
   if (osmesa->format != OSMESA_RGBA &&
321
   if (osmesa->format != OSMESA_RGBA &&
322
       osmesa->format != OSMESA_BGRA &&
322
       osmesa->format != OSMESA_BGRA &&
323
       osmesa->format != OSMESA_ARGB)   return (swrast_tri_func) NULL;
323
       osmesa->format != OSMESA_ARGB)   return (swrast_tri_func) NULL;
324
   if (ctx->Polygon.CullFlag &&
324
   if (ctx->Polygon.CullFlag &&
325
       ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
325
       ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
326
                                        return (swrast_tri_func) NULL;
326
                                        return (swrast_tri_func) NULL;
327
 
327
 
328
   if (swrast->_RasterMask == DEPTH_BIT &&
328
   if (swrast->_RasterMask == DEPTH_BIT &&
329
       ctx->Depth.Func == GL_LESS &&
329
       ctx->Depth.Func == GL_LESS &&
330
       ctx->Depth.Mask == GL_TRUE &&
330
       ctx->Depth.Mask == GL_TRUE &&
331
       ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
331
       ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
332
      if (ctx->Light.ShadeModel == GL_SMOOTH) {
332
      if (ctx->Light.ShadeModel == GL_SMOOTH) {
333
         return (swrast_tri_func) smooth_rgba_z_triangle;
333
         return (swrast_tri_func) smooth_rgba_z_triangle;
334
      }
334
      }
335
      else {
335
      else {
336
         return (swrast_tri_func) flat_rgba_z_triangle;
336
         return (swrast_tri_func) flat_rgba_z_triangle;
337
      }
337
      }
338
   }
338
   }
339
   return (swrast_tri_func) NULL;
339
   return (swrast_tri_func) NULL;
340
}
340
}
341
 
341
 
342
 
342
 
343
 
343
 
344
/* Override for the swrast triangle-selection function.  Try to use one
344
/* Override for the swrast triangle-selection function.  Try to use one
345
 * of our internal triangle functions, otherwise fall back to the
345
 * of our internal triangle functions, otherwise fall back to the
346
 * standard swrast functions.
346
 * standard swrast functions.
347
 */
347
 */
348
static void
348
static void
349
osmesa_choose_triangle( struct gl_context *ctx )
349
osmesa_choose_triangle( struct gl_context *ctx )
350
{
350
{
351
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
351
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
352
 
352
 
353
   swrast->Triangle = osmesa_choose_triangle_function( ctx );
353
   swrast->Triangle = osmesa_choose_triangle_function( ctx );
354
   if (!swrast->Triangle)
354
   if (!swrast->Triangle)
355
      _swrast_choose_triangle( ctx );
355
      _swrast_choose_triangle( ctx );
356
}
356
}
357
 
357
 
358
static void
358
static void
359
osmesa_choose_line( struct gl_context *ctx )
359
osmesa_choose_line( struct gl_context *ctx )
360
{
360
{
361
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
361
   SWcontext *swrast = SWRAST_CONTEXT(ctx);
362
 
362
 
363
   swrast->Line = osmesa_choose_line_function( ctx );
363
   swrast->Line = osmesa_choose_line_function( ctx );
364
   if (!swrast->Line)
364
   if (!swrast->Line)
365
      _swrast_choose_line( ctx );
365
      _swrast_choose_line( ctx );
366
}
366
}
367
 
367
 
368
 
368
 
369
 
369
 
370
/**
370
/**
371
 * Recompute the values of the context's rowaddr array.
371
 * Recompute the values of the context's rowaddr array.
372
 */
372
 */
373
static void
373
static void
374
compute_row_addresses( OSMesaContext osmesa )
374
compute_row_addresses( OSMesaContext osmesa )
375
{
375
{
376
   GLint bytesPerRow, i;
376
   GLint bytesPerRow, i;
377
   GLubyte *origin = (GLubyte *) osmesa->srb->Buffer;
377
   GLubyte *origin = (GLubyte *) osmesa->srb->Buffer;
378
   GLint rowlength; /* in pixels */
378
   GLint rowlength; /* in pixels */
379
   GLint height = osmesa->srb->Base.Height;
379
   GLint height = osmesa->srb->Base.Height;
380
 
380
 
381
   if (osmesa->userRowLength)
381
   if (osmesa->userRowLength)
382
      rowlength = osmesa->userRowLength;
382
      rowlength = osmesa->userRowLength;
383
   else
383
   else
384
      rowlength = osmesa->srb->Base.Width;
384
      rowlength = osmesa->srb->Base.Width;
385
 
385
 
386
   bytesPerRow = rowlength * _mesa_get_format_bytes(osmesa->srb->Base.Format);
386
   bytesPerRow = rowlength * _mesa_get_format_bytes(osmesa->srb->Base.Format);
387
 
387
 
388
   if (osmesa->yup) {
388
   if (osmesa->yup) {
389
      /* Y=0 is bottom line of window */
389
      /* Y=0 is bottom line of window */
390
      for (i = 0; i < height; i++) {
390
      for (i = 0; i < height; i++) {
391
         osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + i * bytesPerRow);
391
         osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + i * bytesPerRow);
392
      }
392
      }
393
   }
393
   }
394
   else {
394
   else {
395
      /* Y=0 is top line of window */
395
      /* Y=0 is top line of window */
396
      for (i = 0; i < height; i++) {
396
      for (i = 0; i < height; i++) {
397
         GLint j = height - i - 1;
397
         GLint j = height - i - 1;
398
         osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + j * bytesPerRow);
398
         osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + j * bytesPerRow);
399
      }
399
      }
400
   }
400
   }
401
}
401
}
402
 
402
 
403
 
403
 
404
 
404
 
405
/**
405
/**
406
 * Don't use _mesa_delete_renderbuffer since we can't free rb->Buffer.
406
 * Don't use _mesa_delete_renderbuffer since we can't free rb->Buffer.
407
 */
407
 */
408
static void
408
static void
409
osmesa_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
409
osmesa_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
410
{
410
{
411
   _mesa_delete_renderbuffer(ctx, rb);
411
   _mesa_delete_renderbuffer(ctx, rb);
412
}
412
}
413
 
413
 
414
 
414
 
415
/**
415
/**
416
 * Allocate renderbuffer storage.  We don't actually allocate any storage
416
 * Allocate renderbuffer storage.  We don't actually allocate any storage
417
 * since we're using a user-provided buffer.
417
 * since we're using a user-provided buffer.
418
 * Just set up all the gl_renderbuffer methods.
418
 * Just set up all the gl_renderbuffer methods.
419
 */
419
 */
420
static GLboolean
420
static GLboolean
421
osmesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
421
osmesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
422
                            GLenum internalFormat, GLuint width, GLuint height)
422
                            GLenum internalFormat, GLuint width, GLuint height)
423
{
423
{
424
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
424
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
425
 
425
 
426
   /* Note: we can ignoring internalFormat for "window-system" renderbuffers */
426
   /* Note: we can ignoring internalFormat for "window-system" renderbuffers */
427
   (void) internalFormat;
427
   (void) internalFormat;
428
 
428
 
429
   /* Given the user-provided format and type, figure out which MESA_FORMAT_x
429
   /* Given the user-provided format and type, figure out which MESA_FORMAT_x
430
    * to use.
430
    * to use.
431
    * XXX There aren't Mesa formats for all the possible combinations here!
431
    * XXX There aren't Mesa formats for all the possible combinations here!
432
    * XXX Specifically, there's only RGBA-order 16-bit/channel and float
432
    * XXX Specifically, there's only RGBA-order 16-bit/channel and float
433
    * XXX formats.
433
    * XXX formats.
434
    * XXX The 8-bit/channel formats should all be OK.
434
    * XXX The 8-bit/channel formats should all be OK.
435
    */
435
    */
436
   if (osmesa->format == OSMESA_RGBA) {
436
   if (osmesa->format == OSMESA_RGBA) {
437
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
437
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
438
         if (_mesa_little_endian())
438
         if (_mesa_little_endian())
439
            rb->Format = MESA_FORMAT_RGBA8888_REV;
439
            rb->Format = MESA_FORMAT_RGBA8888_REV;
440
         else
440
         else
441
            rb->Format = MESA_FORMAT_RGBA8888;
441
            rb->Format = MESA_FORMAT_RGBA8888;
442
      }
442
      }
443
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
443
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
444
         rb->Format = MESA_FORMAT_RGBA_16;
444
         rb->Format = MESA_FORMAT_RGBA_16;
445
      }
445
      }
446
      else {
446
      else {
447
         rb->Format = MESA_FORMAT_RGBA_FLOAT32;
447
         rb->Format = MESA_FORMAT_RGBA_FLOAT32;
448
      }
448
      }
449
   }
449
   }
450
   else if (osmesa->format == OSMESA_BGRA) {
450
   else if (osmesa->format == OSMESA_BGRA) {
451
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
451
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
452
         if (_mesa_little_endian())
452
         if (_mesa_little_endian())
453
            rb->Format = MESA_FORMAT_ARGB8888;
453
            rb->Format = MESA_FORMAT_ARGB8888;
454
         else
454
         else
455
            rb->Format = MESA_FORMAT_ARGB8888_REV;
455
            rb->Format = MESA_FORMAT_ARGB8888_REV;
456
      }
456
      }
457
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
457
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
458
         _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLushort");
458
         _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLushort");
459
         rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
459
         rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
460
      }
460
      }
461
      else {
461
      else {
462
         _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLfloat");
462
         _mesa_warning(ctx, "Unsupported OSMesa format BGRA/GLfloat");
463
         rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
463
         rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
464
      }
464
      }
465
   }
465
   }
466
   else if (osmesa->format == OSMESA_ARGB) {
466
   else if (osmesa->format == OSMESA_ARGB) {
467
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
467
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
468
         if (_mesa_little_endian())
468
         if (_mesa_little_endian())
469
            rb->Format = MESA_FORMAT_ARGB8888_REV;
469
            rb->Format = MESA_FORMAT_ARGB8888_REV;
470
         else
470
         else
471
            rb->Format = MESA_FORMAT_ARGB8888;
471
            rb->Format = MESA_FORMAT_ARGB8888;
472
      }
472
      }
473
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
473
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
474
         _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLushort");
474
         _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLushort");
475
         rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
475
         rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
476
      }
476
      }
477
      else {
477
      else {
478
         _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLfloat");
478
         _mesa_warning(ctx, "Unsupported OSMesa format ARGB/GLfloat");
479
         rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
479
         rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
480
      }
480
      }
481
   }
481
   }
482
   else if (osmesa->format == OSMESA_RGB) {
482
   else if (osmesa->format == OSMESA_RGB) {
483
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
483
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
484
         rb->Format = MESA_FORMAT_RGB888;
484
         rb->Format = MESA_FORMAT_RGB888;
485
      }
485
      }
486
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
486
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
487
         _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLushort");
487
         _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLushort");
488
         rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
488
         rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
489
      }
489
      }
490
      else {
490
      else {
491
         _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLfloat");
491
         _mesa_warning(ctx, "Unsupported OSMesa format RGB/GLfloat");
492
         rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
492
         rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
493
      }
493
      }
494
   }
494
   }
495
   else if (osmesa->format == OSMESA_BGR) {
495
   else if (osmesa->format == OSMESA_BGR) {
496
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
496
      if (osmesa->DataType == GL_UNSIGNED_BYTE) {
497
         rb->Format = MESA_FORMAT_BGR888;
497
         rb->Format = MESA_FORMAT_BGR888;
498
      }
498
      }
499
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
499
      else if (osmesa->DataType == GL_UNSIGNED_SHORT) {
500
         _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLushort");
500
         _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLushort");
501
         rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
501
         rb->Format = MESA_FORMAT_RGBA_16; /* not exactly right */
502
      }
502
      }
503
      else {
503
      else {
504
         _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLfloat");
504
         _mesa_warning(ctx, "Unsupported OSMesa format BGR/GLfloat");
505
         rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
505
         rb->Format = MESA_FORMAT_RGBA_FLOAT32; /* not exactly right */
506
      }
506
      }
507
   }
507
   }
508
   else if (osmesa->format == OSMESA_RGB_565) {
508
   else if (osmesa->format == OSMESA_RGB_565) {
509
      ASSERT(osmesa->DataType == GL_UNSIGNED_BYTE);
509
      ASSERT(osmesa->DataType == GL_UNSIGNED_BYTE);
510
      rb->Format = MESA_FORMAT_RGB565;
510
      rb->Format = MESA_FORMAT_RGB565;
511
   }
511
   }
512
   else {
512
   else {
513
      _mesa_problem(ctx, "bad pixel format in osmesa renderbuffer_storage");
513
      _mesa_problem(ctx, "bad pixel format in osmesa renderbuffer_storage");
514
   }
514
   }
515
 
515
 
516
   rb->Width = width;
516
   rb->Width = width;
517
   rb->Height = height;
517
   rb->Height = height;
518
 
518
 
519
   compute_row_addresses( osmesa );
519
   compute_row_addresses( osmesa );
520
 
520
 
521
   return GL_TRUE;
521
   return GL_TRUE;
522
}
522
}
523
 
523
 
524
 
524
 
525
/**
525
/**
526
 * Allocate a new renderbuffer to describe the user-provided color buffer.
526
 * Allocate a new renderbuffer to describe the user-provided color buffer.
527
 */
527
 */
528
static struct swrast_renderbuffer *
528
static struct swrast_renderbuffer *
529
new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type)
529
new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type)
530
{
530
{
531
   const GLuint name = 0;
531
   const GLuint name = 0;
532
   struct swrast_renderbuffer *srb = CALLOC_STRUCT(swrast_renderbuffer);
532
   struct swrast_renderbuffer *srb = CALLOC_STRUCT(swrast_renderbuffer);
533
 
533
 
534
   if (srb) {
534
   if (srb) {
535
      _mesa_init_renderbuffer(&srb->Base, name);
535
      _mesa_init_renderbuffer(&srb->Base, name);
536
 
536
 
537
      srb->Base.ClassID = OSMESA_RENDERBUFFER_CLASS;
537
      srb->Base.ClassID = OSMESA_RENDERBUFFER_CLASS;
538
      srb->Base.RefCount = 1;
538
      srb->Base.RefCount = 1;
539
      srb->Base.Delete = osmesa_delete_renderbuffer;
539
      srb->Base.Delete = osmesa_delete_renderbuffer;
540
      srb->Base.AllocStorage = osmesa_renderbuffer_storage;
540
      srb->Base.AllocStorage = osmesa_renderbuffer_storage;
541
 
541
 
542
      srb->Base.InternalFormat = GL_RGBA;
542
      srb->Base.InternalFormat = GL_RGBA;
543
      srb->Base._BaseFormat = GL_RGBA;
543
      srb->Base._BaseFormat = GL_RGBA;
544
 
544
 
545
      return srb;
545
      return srb;
546
   }
546
   }
547
   return NULL;
547
   return NULL;
548
}
548
}
549
 
549
 
550
 
550
 
551
 
551
 
552
static void
552
static void
553
osmesa_MapRenderbuffer(struct gl_context *ctx,
553
osmesa_MapRenderbuffer(struct gl_context *ctx,
554
                       struct gl_renderbuffer *rb,
554
                       struct gl_renderbuffer *rb,
555
                       GLuint x, GLuint y, GLuint w, GLuint h,
555
                       GLuint x, GLuint y, GLuint w, GLuint h,
556
                       GLbitfield mode,
556
                       GLbitfield mode,
557
                       GLubyte **mapOut, GLint *rowStrideOut)
557
                       GLubyte **mapOut, GLint *rowStrideOut)
558
{
558
{
559
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
559
   const OSMesaContext osmesa = OSMESA_CONTEXT(ctx);
560
 
560
 
561
   if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
561
   if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
562
      /* this is an OSMesa renderbuffer which wraps user memory */
562
      /* this is an OSMesa renderbuffer which wraps user memory */
563
      struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
563
      struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
564
      const GLuint bpp = _mesa_get_format_bytes(rb->Format);
564
      const GLuint bpp = _mesa_get_format_bytes(rb->Format);
565
      GLint rowStride; /* in bytes */
565
      GLint rowStride; /* in bytes */
566
 
566
 
567
      if (osmesa->userRowLength)
567
      if (osmesa->userRowLength)
568
         rowStride = osmesa->userRowLength * bpp;
568
         rowStride = osmesa->userRowLength * bpp;
569
      else
569
      else
570
         rowStride = rb->Width * bpp;
570
         rowStride = rb->Width * bpp;
571
 
571
 
572
      if (!osmesa->yup) {
572
      if (!osmesa->yup) {
573
         /* Y=0 is top line of window */
573
         /* Y=0 is top line of window */
574
         y = rb->Height - y - 1;
574
         y = rb->Height - y - 1;
575
         *rowStrideOut = -rowStride;
575
         *rowStrideOut = -rowStride;
576
      }
576
      }
577
      else {
577
      else {
578
         *rowStrideOut = rowStride;
578
         *rowStrideOut = rowStride;
579
      }
579
      }
580
 
580
 
581
      *mapOut = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
581
      *mapOut = (GLubyte *) srb->Buffer + y * rowStride + x * bpp;
582
   }
582
   }
583
   else {
583
   else {
584
      _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
584
      _swrast_map_soft_renderbuffer(ctx, rb, x, y, w, h, mode,
585
                                    mapOut, rowStrideOut);
585
                                    mapOut, rowStrideOut);
586
   }
586
   }
587
}
587
}
588
 
588
 
589
 
589
 
590
static void
590
static void
591
osmesa_UnmapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
591
osmesa_UnmapRenderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb)
592
{
592
{
593
   if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
593
   if (rb->ClassID == OSMESA_RENDERBUFFER_CLASS) {
594
      /* no-op */
594
      /* no-op */
595
   }
595
   }
596
   else {
596
   else {
597
      _swrast_unmap_soft_renderbuffer(ctx, rb);
597
      _swrast_unmap_soft_renderbuffer(ctx, rb);
598
   }
598
   }
599
}
599
}
600
 
600
 
601
 
601
 
602
/**********************************************************************/
602
/**********************************************************************/
603
/*****                    Public Functions                        *****/
603
/*****                    Public Functions                        *****/
604
/**********************************************************************/
604
/**********************************************************************/
605
 
605
 
606
 
606
 
607
/**
607
/**
608
 * Create an Off-Screen Mesa rendering context.  The only attribute needed is
608
 * Create an Off-Screen Mesa rendering context.  The only attribute needed is
609
 * an RGBA vs Color-Index mode flag.
609
 * an RGBA vs Color-Index mode flag.
610
 *
610
 *
611
 * Input:  format - Must be GL_RGBA
611
 * Input:  format - Must be GL_RGBA
612
 *         sharelist - specifies another OSMesaContext with which to share
612
 *         sharelist - specifies another OSMesaContext with which to share
613
 *                     display lists.  NULL indicates no sharing.
613
 *                     display lists.  NULL indicates no sharing.
614
 * Return:  an OSMesaContext or 0 if error
614
 * Return:  an OSMesaContext or 0 if error
615
 */
615
 */
616
GLAPI OSMesaContext GLAPIENTRY
616
GLAPI OSMesaContext GLAPIENTRY
617
OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
617
OSMesaCreateContext( GLenum format, OSMesaContext sharelist )
618
{
618
{
619
   return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
619
   return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS,
620
                                 8, 0, sharelist);
620
                                 8, 0, sharelist);
621
}
621
}
622
 
622
 
623
 
623
 
624
 
624
 
625
/**
625
/**
626
 * New in Mesa 3.5
626
 * New in Mesa 3.5
627
 *
627
 *
628
 * Create context and specify size of ancillary buffers.
628
 * Create context and specify size of ancillary buffers.
629
 */
629
 */
630
GLAPI OSMesaContext GLAPIENTRY
630
GLAPI OSMesaContext GLAPIENTRY
631
OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
631
OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
632
                        GLint accumBits, OSMesaContext sharelist )
632
                        GLint accumBits, OSMesaContext sharelist )
633
{
633
{
634
   OSMesaContext osmesa;
634
   OSMesaContext osmesa;
635
   struct dd_function_table functions;
635
   struct dd_function_table functions;
636
   GLint rind, gind, bind, aind;
636
   GLint rind, gind, bind, aind;
637
   GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
637
   GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
638
 
638
 
639
   rind = gind = bind = aind = 0;
639
   rind = gind = bind = aind = 0;
640
   if (format==OSMESA_RGBA) {
640
   if (format==OSMESA_RGBA) {
641
      redBits = CHAN_BITS;
641
      redBits = CHAN_BITS;
642
      greenBits = CHAN_BITS;
642
      greenBits = CHAN_BITS;
643
      blueBits = CHAN_BITS;
643
      blueBits = CHAN_BITS;
644
      alphaBits = CHAN_BITS;
644
      alphaBits = CHAN_BITS;
645
      rind = 0;
645
      rind = 0;
646
      gind = 1;
646
      gind = 1;
647
      bind = 2;
647
      bind = 2;
648
      aind = 3;
648
      aind = 3;
649
   }
649
   }
650
   else if (format==OSMESA_BGRA) {
650
   else if (format==OSMESA_BGRA) {
651
      redBits = CHAN_BITS;
651
      redBits = CHAN_BITS;
652
      greenBits = CHAN_BITS;
652
      greenBits = CHAN_BITS;
653
      blueBits = CHAN_BITS;
653
      blueBits = CHAN_BITS;
654
      alphaBits = CHAN_BITS;
654
      alphaBits = CHAN_BITS;
655
      bind = 0;
655
      bind = 0;
656
      gind = 1;
656
      gind = 1;
657
      rind = 2;
657
      rind = 2;
658
      aind = 3;
658
      aind = 3;
659
   }
659
   }
660
   else if (format==OSMESA_ARGB) {
660
   else if (format==OSMESA_ARGB) {
661
      redBits = CHAN_BITS;
661
      redBits = CHAN_BITS;
662
      greenBits = CHAN_BITS;
662
      greenBits = CHAN_BITS;
663
      blueBits = CHAN_BITS;
663
      blueBits = CHAN_BITS;
664
      alphaBits = CHAN_BITS;
664
      alphaBits = CHAN_BITS;
665
      aind = 0;
665
      aind = 0;
666
      rind = 1;
666
      rind = 1;
667
      gind = 2;
667
      gind = 2;
668
      bind = 3;
668
      bind = 3;
669
   }
669
   }
670
   else if (format==OSMESA_RGB) {
670
   else if (format==OSMESA_RGB) {
671
      redBits = CHAN_BITS;
671
      redBits = CHAN_BITS;
672
      greenBits = CHAN_BITS;
672
      greenBits = CHAN_BITS;
673
      blueBits = CHAN_BITS;
673
      blueBits = CHAN_BITS;
674
      alphaBits = 0;
674
      alphaBits = 0;
675
      rind = 0;
675
      rind = 0;
676
      gind = 1;
676
      gind = 1;
677
      bind = 2;
677
      bind = 2;
678
   }
678
   }
679
   else if (format==OSMESA_BGR) {
679
   else if (format==OSMESA_BGR) {
680
      redBits = CHAN_BITS;
680
      redBits = CHAN_BITS;
681
      greenBits = CHAN_BITS;
681
      greenBits = CHAN_BITS;
682
      blueBits = CHAN_BITS;
682
      blueBits = CHAN_BITS;
683
      alphaBits = 0;
683
      alphaBits = 0;
684
      rind = 2;
684
      rind = 2;
685
      gind = 1;
685
      gind = 1;
686
      bind = 0;
686
      bind = 0;
687
   }
687
   }
688
#if CHAN_TYPE == GL_UNSIGNED_BYTE
688
#if CHAN_TYPE == GL_UNSIGNED_BYTE
689
   else if (format==OSMESA_RGB_565) {
689
   else if (format==OSMESA_RGB_565) {
690
      redBits = 5;
690
      redBits = 5;
691
      greenBits = 6;
691
      greenBits = 6;
692
      blueBits = 5;
692
      blueBits = 5;
693
      alphaBits = 0;
693
      alphaBits = 0;
694
      rind = 0; /* not used */
694
      rind = 0; /* not used */
695
      gind = 0;
695
      gind = 0;
696
      bind = 0;
696
      bind = 0;
697
   }
697
   }
698
#endif
698
#endif
699
   else {
699
   else {
700
      return NULL;
700
      return NULL;
701
   }
701
   }
702
 
702
 
703
   osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
703
   osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
704
   if (osmesa) {
704
   if (osmesa) {
705
      osmesa->gl_visual = _mesa_create_visual( GL_FALSE,    /* double buffer */
705
      osmesa->gl_visual = _mesa_create_visual( GL_FALSE,    /* double buffer */
706
                                               GL_FALSE,    /* stereo */
706
                                               GL_FALSE,    /* stereo */
707
                                               redBits,
707
                                               redBits,
708
                                               greenBits,
708
                                               greenBits,
709
                                               blueBits,
709
                                               blueBits,
710
                                               alphaBits,
710
                                               alphaBits,
711
                                               depthBits,
711
                                               depthBits,
712
                                               stencilBits,
712
                                               stencilBits,
713
                                               accumBits,
713
                                               accumBits,
714
                                               accumBits,
714
                                               accumBits,
715
                                               accumBits,
715
                                               accumBits,
716
                                               alphaBits ? accumBits : 0,
716
                                               alphaBits ? accumBits : 0,
717
                                               1            /* num samples */
717
                                               1            /* num samples */
718
                                               );
718
                                               );
719
      if (!osmesa->gl_visual) {
719
      if (!osmesa->gl_visual) {
720
         free(osmesa);
720
         free(osmesa);
721
         return NULL;
721
         return NULL;
722
      }
722
      }
723
 
723
 
724
      /* Initialize device driver function table */
724
      /* Initialize device driver function table */
725
      _mesa_init_driver_functions(&functions);
725
      _mesa_init_driver_functions(&functions);
726
      /* override with our functions */
726
      /* override with our functions */
727
      functions.GetString = get_string;
727
      functions.GetString = get_string;
728
      functions.UpdateState = osmesa_update_state;
728
      functions.UpdateState = osmesa_update_state;
729
 
729
 
730
      if (!_mesa_initialize_context(&osmesa->mesa,
730
      if (!_mesa_initialize_context(&osmesa->mesa,
731
                                    API_OPENGL_COMPAT,
731
                                    API_OPENGL_COMPAT,
732
                                    osmesa->gl_visual,
732
                                    osmesa->gl_visual,
733
                                    sharelist ? &sharelist->mesa
733
                                    sharelist ? &sharelist->mesa
734
                                              : (struct gl_context *) NULL,
734
                                              : (struct gl_context *) NULL,
735
                                    &functions)) {
735
                                    &functions)) {
736
         _mesa_destroy_visual( osmesa->gl_visual );
736
         _mesa_destroy_visual( osmesa->gl_visual );
737
         free(osmesa);
737
         free(osmesa);
738
         return NULL;
738
         return NULL;
739
      }
739
      }
740
 
740
 
741
      _mesa_enable_sw_extensions(&(osmesa->mesa));
741
      _mesa_enable_sw_extensions(&(osmesa->mesa));
742
 
742
 
743
      osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
743
      osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
744
      if (!osmesa->gl_buffer) {
744
      if (!osmesa->gl_buffer) {
745
         _mesa_destroy_visual( osmesa->gl_visual );
745
         _mesa_destroy_visual( osmesa->gl_visual );
746
         _mesa_free_context_data( &osmesa->mesa );
746
         _mesa_free_context_data( &osmesa->mesa );
747
         free(osmesa);
747
         free(osmesa);
748
         return NULL;
748
         return NULL;
749
      }
749
      }
750
 
750
 
751
      /* Create depth/stencil/accum buffers.  We'll create the color
751
      /* Create depth/stencil/accum buffers.  We'll create the color
752
       * buffer later in OSMesaMakeCurrent().
752
       * buffer later in OSMesaMakeCurrent().
753
       */
753
       */
754
      _swrast_add_soft_renderbuffers(osmesa->gl_buffer,
754
      _swrast_add_soft_renderbuffers(osmesa->gl_buffer,
755
                                     GL_FALSE, /* color */
755
                                     GL_FALSE, /* color */
756
                                     osmesa->gl_visual->haveDepthBuffer,
756
                                     osmesa->gl_visual->haveDepthBuffer,
757
                                     osmesa->gl_visual->haveStencilBuffer,
757
                                     osmesa->gl_visual->haveStencilBuffer,
758
                                     osmesa->gl_visual->haveAccumBuffer,
758
                                     osmesa->gl_visual->haveAccumBuffer,
759
                                     GL_FALSE, /* alpha */
759
                                     GL_FALSE, /* alpha */
760
                                     GL_FALSE /* aux */ );
760
                                     GL_FALSE /* aux */ );
761
 
761
 
762
      osmesa->format = format;
762
      osmesa->format = format;
763
      osmesa->userRowLength = 0;
763
      osmesa->userRowLength = 0;
764
      osmesa->yup = GL_TRUE;
764
      osmesa->yup = GL_TRUE;
765
      osmesa->rInd = rind;
765
      osmesa->rInd = rind;
766
      osmesa->gInd = gind;
766
      osmesa->gInd = gind;
767
      osmesa->bInd = bind;
767
      osmesa->bInd = bind;
768
      osmesa->aInd = aind;
768
      osmesa->aInd = aind;
769
 
769
 
770
      _mesa_meta_init(&osmesa->mesa);
770
      _mesa_meta_init(&osmesa->mesa);
771
 
771
 
772
      /* Initialize the software rasterizer and helper modules. */
772
      /* Initialize the software rasterizer and helper modules. */
773
      {
773
      {
774
	 struct gl_context *ctx = &osmesa->mesa;
774
	 struct gl_context *ctx = &osmesa->mesa;
775
         SWcontext *swrast;
775
         SWcontext *swrast;
776
         TNLcontext *tnl;
776
         TNLcontext *tnl;
777
 
777
 
778
	 if (!_swrast_CreateContext( ctx ) ||
778
	 if (!_swrast_CreateContext( ctx ) ||
779
             !_vbo_CreateContext( ctx ) ||
779
             !_vbo_CreateContext( ctx ) ||
780
             !_tnl_CreateContext( ctx ) ||
780
             !_tnl_CreateContext( ctx ) ||
781
             !_swsetup_CreateContext( ctx )) {
781
             !_swsetup_CreateContext( ctx )) {
782
            _mesa_destroy_visual(osmesa->gl_visual);
782
            _mesa_destroy_visual(osmesa->gl_visual);
783
            _mesa_free_context_data(ctx);
783
            _mesa_free_context_data(ctx);
784
            free(osmesa);
784
            free(osmesa);
785
            return NULL;
785
            return NULL;
786
         }
786
         }
787
 
787
 
788
	 _swsetup_Wakeup( ctx );
788
	 _swsetup_Wakeup( ctx );
789
 
789
 
790
         /* use default TCL pipeline */
790
         /* use default TCL pipeline */
791
         tnl = TNL_CONTEXT(ctx);
791
         tnl = TNL_CONTEXT(ctx);
792
         tnl->Driver.RunPipeline = _tnl_run_pipeline;
792
         tnl->Driver.RunPipeline = _tnl_run_pipeline;
793
 
793
 
794
         ctx->Driver.MapRenderbuffer = osmesa_MapRenderbuffer;
794
         ctx->Driver.MapRenderbuffer = osmesa_MapRenderbuffer;
795
         ctx->Driver.UnmapRenderbuffer = osmesa_UnmapRenderbuffer;
795
         ctx->Driver.UnmapRenderbuffer = osmesa_UnmapRenderbuffer;
796
 
796
 
797
         ctx->Driver.GenerateMipmap = _mesa_generate_mipmap;
797
         ctx->Driver.GenerateMipmap = _mesa_generate_mipmap;
798
 
798
 
799
         /* Extend the software rasterizer with our optimized line and triangle
799
         /* Extend the software rasterizer with our optimized line and triangle
800
          * drawing functions.
800
          * drawing functions.
801
          */
801
          */
802
         swrast = SWRAST_CONTEXT( ctx );
802
         swrast = SWRAST_CONTEXT( ctx );
803
         swrast->choose_line = osmesa_choose_line;
803
         swrast->choose_line = osmesa_choose_line;
804
         swrast->choose_triangle = osmesa_choose_triangle;
804
         swrast->choose_triangle = osmesa_choose_triangle;
805
 
805
 
806
         _mesa_compute_version(ctx);
806
         _mesa_compute_version(ctx);
807
 
807
 
808
         /* Exec table initialization requires the version to be computed */
808
         /* Exec table initialization requires the version to be computed */
809
         _mesa_initialize_dispatch_tables(ctx);
809
         _mesa_initialize_dispatch_tables(ctx);
810
         _mesa_initialize_vbo_vtxfmt(ctx);
810
         _mesa_initialize_vbo_vtxfmt(ctx);
811
      }
811
      }
812
   }
812
   }
813
   return osmesa;
813
   return osmesa;
814
}
814
}
815
 
815
 
816
 
816
 
817
/**
817
/**
818
 * Destroy an Off-Screen Mesa rendering context.
818
 * Destroy an Off-Screen Mesa rendering context.
819
 *
819
 *
820
 * \param osmesa  the context to destroy
820
 * \param osmesa  the context to destroy
821
 */
821
 */
822
GLAPI void GLAPIENTRY
822
GLAPI void GLAPIENTRY
823
OSMesaDestroyContext( OSMesaContext osmesa )
823
OSMesaDestroyContext( OSMesaContext osmesa )
824
{
824
{
825
   if (osmesa) {
825
   if (osmesa) {
826
      if (osmesa->srb)
826
      if (osmesa->srb)
827
         _mesa_reference_renderbuffer((struct gl_renderbuffer **) &osmesa->srb, NULL);
827
         _mesa_reference_renderbuffer((struct gl_renderbuffer **) &osmesa->srb, NULL);
828
 
828
 
829
      _mesa_meta_free( &osmesa->mesa );
829
      _mesa_meta_free( &osmesa->mesa );
830
 
830
 
831
      _swsetup_DestroyContext( &osmesa->mesa );
831
      _swsetup_DestroyContext( &osmesa->mesa );
832
      _tnl_DestroyContext( &osmesa->mesa );
832
      _tnl_DestroyContext( &osmesa->mesa );
833
      _vbo_DestroyContext( &osmesa->mesa );
833
      _vbo_DestroyContext( &osmesa->mesa );
834
      _swrast_DestroyContext( &osmesa->mesa );
834
      _swrast_DestroyContext( &osmesa->mesa );
835
 
835
 
836
      _mesa_destroy_visual( osmesa->gl_visual );
836
      _mesa_destroy_visual( osmesa->gl_visual );
837
      _mesa_reference_framebuffer( &osmesa->gl_buffer, NULL );
837
      _mesa_reference_framebuffer( &osmesa->gl_buffer, NULL );
838
 
838
 
839
      _mesa_free_context_data( &osmesa->mesa );
839
      _mesa_free_context_data( &osmesa->mesa );
840
      free( osmesa );
840
      free( osmesa );
841
   }
841
   }
842
}
842
}
843
 
843
 
844
 
844
 
845
/**
845
/**
846
 * Bind an OSMesaContext to an image buffer.  The image buffer is just a
846
 * Bind an OSMesaContext to an image buffer.  The image buffer is just a
847
 * block of memory which the client provides.  Its size must be at least
847
 * block of memory which the client provides.  Its size must be at least
848
 * as large as width*height*sizeof(type).  Its address should be a multiple
848
 * as large as width*height*sizeof(type).  Its address should be a multiple
849
 * of 4 if using RGBA mode.
849
 * of 4 if using RGBA mode.
850
 *
850
 *
851
 * Image data is stored in the order of glDrawPixels:  row-major order
851
 * Image data is stored in the order of glDrawPixels:  row-major order
852
 * with the lower-left image pixel stored in the first array position
852
 * with the lower-left image pixel stored in the first array position
853
 * (ie. bottom-to-top).
853
 * (ie. bottom-to-top).
854
 *
854
 *
855
 * If the context's viewport hasn't been initialized yet, it will now be
855
 * If the context's viewport hasn't been initialized yet, it will now be
856
 * initialized to (0,0,width,height).
856
 * initialized to (0,0,width,height).
857
 *
857
 *
858
 * Input:  osmesa - the rendering context
858
 * Input:  osmesa - the rendering context
859
 *         buffer - the image buffer memory
859
 *         buffer - the image buffer memory
860
 *         type - data type for pixel components
860
 *         type - data type for pixel components
861
 *            Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5
861
 *            Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5
862
 *            are supported.  But if Mesa's been compiled with CHAN_BITS==16
862
 *            are supported.  But if Mesa's been compiled with CHAN_BITS==16
863
 *            then type may be GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.  And if
863
 *            then type may be GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.  And if
864
 *            Mesa's been build with CHAN_BITS==32 then type may be GL_FLOAT,
864
 *            Mesa's been build with CHAN_BITS==32 then type may be GL_FLOAT,
865
 *            GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.
865
 *            GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE.
866
 *         width, height - size of image buffer in pixels, at least 1
866
 *         width, height - size of image buffer in pixels, at least 1
867
 * Return:  GL_TRUE if success, GL_FALSE if error because of invalid osmesa,
867
 * Return:  GL_TRUE if success, GL_FALSE if error because of invalid osmesa,
868
 *          invalid buffer address, invalid type, width<1, height<1,
868
 *          invalid buffer address, invalid type, width<1, height<1,
869
 *          width>internal limit or height>internal limit.
869
 *          width>internal limit or height>internal limit.
870
 */
870
 */
871
GLAPI GLboolean GLAPIENTRY
871
GLAPI GLboolean GLAPIENTRY
872
OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type,
872
OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type,
873
                   GLsizei width, GLsizei height )
873
                   GLsizei width, GLsizei height )
874
{
874
{
875
   if (!osmesa || !buffer ||
875
   if (!osmesa || !buffer ||
876
       width < 1 || height < 1 ||
876
       width < 1 || height < 1 ||
877
       width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) {
877
       width > SWRAST_MAX_WIDTH || height > SWRAST_MAX_HEIGHT) {
878
      return GL_FALSE;
878
      return GL_FALSE;
879
   }
879
   }
880
 
880
 
881
   if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) {
881
   if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) {
882
      return GL_FALSE;
882
      return GL_FALSE;
883
   }
883
   }
884
 
884
 
885
#if 0
885
#if 0
886
   if (!(type == GL_UNSIGNED_BYTE ||
886
   if (!(type == GL_UNSIGNED_BYTE ||
887
         (type == GL_UNSIGNED_SHORT && CHAN_BITS >= 16) ||
887
         (type == GL_UNSIGNED_SHORT && CHAN_BITS >= 16) ||
888
         (type == GL_FLOAT && CHAN_BITS == 32))) {
888
         (type == GL_FLOAT && CHAN_BITS == 32))) {
889
      /* i.e. is sizeof(type) * 8 > CHAN_BITS? */
889
      /* i.e. is sizeof(type) * 8 > CHAN_BITS? */
890
      return GL_FALSE;
890
      return GL_FALSE;
891
   }
891
   }
892
#endif
892
#endif
893
 
893
 
894
   osmesa_update_state( &osmesa->mesa, 0 );
894
   osmesa_update_state( &osmesa->mesa, 0 );
895
 
895
 
896
   /* Call this periodically to detect when the user has begun using
896
   /* Call this periodically to detect when the user has begun using
897
    * GL rendering from multiple threads.
897
    * GL rendering from multiple threads.
898
    */
898
    */
899
   _glapi_check_multithread();
899
   _glapi_check_multithread();
900
 
900
 
901
 
901
 
902
   /* Create a front/left color buffer which wraps the user-provided buffer.
902
   /* Create a front/left color buffer which wraps the user-provided buffer.
903
    * There is no back color buffer.
903
    * There is no back color buffer.
904
    * If the user tries to use a 8, 16 or 32-bit/channel buffer that
904
    * If the user tries to use a 8, 16 or 32-bit/channel buffer that
905
    * doesn't match what Mesa was compiled for (CHAN_BITS) the
905
    * doesn't match what Mesa was compiled for (CHAN_BITS) the
906
    * _mesa_add_renderbuffer() function will create a "wrapper" renderbuffer
906
    * _mesa_add_renderbuffer() function will create a "wrapper" renderbuffer
907
    * that converts rendering from CHAN_BITS to the user-requested channel
907
    * that converts rendering from CHAN_BITS to the user-requested channel
908
    * size.
908
    * size.
909
    */
909
    */
910
   if (!osmesa->srb) {
910
   if (!osmesa->srb) {
911
      osmesa->srb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type);
911
      osmesa->srb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type);
912
      _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
912
      _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
913
      _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
913
      _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
914
                             &osmesa->srb->Base);
914
                             &osmesa->srb->Base);
915
      assert(osmesa->srb->Base.RefCount == 2);
915
      assert(osmesa->srb->Base.RefCount == 2);
916
   }
916
   }
917
 
917
 
918
   osmesa->DataType = type;
918
   osmesa->DataType = type;
919
 
919
 
920
   /* Set renderbuffer fields.  Set width/height = 0 to force
920
   /* Set renderbuffer fields.  Set width/height = 0 to force
921
    * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer()
921
    * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer()
922
    */
922
    */
923
   osmesa->srb->Buffer = buffer;
923
   osmesa->srb->Buffer = buffer;
924
   osmesa->srb->Base.Width = osmesa->srb->Base.Height = 0;
924
   osmesa->srb->Base.Width = osmesa->srb->Base.Height = 0;
925
 
925
 
926
   /* Set the framebuffer's size.  This causes the
926
   /* Set the framebuffer's size.  This causes the
927
    * osmesa_renderbuffer_storage() function to get called.
927
    * osmesa_renderbuffer_storage() function to get called.
928
    */
928
    */
929
   _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
929
   _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
930
 
930
 
931
   _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer );
931
   _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer );
932
 
932
 
933
   /* Remove renderbuffer attachment, then re-add.  This installs the
933
   /* Remove renderbuffer attachment, then re-add.  This installs the
934
    * renderbuffer adaptor/wrapper if needed (for bpp conversion).
934
    * renderbuffer adaptor/wrapper if needed (for bpp conversion).
935
    */
935
    */
936
   _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
936
   _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
937
   _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
937
   _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
938
                          &osmesa->srb->Base);
938
                          &osmesa->srb->Base);
939
 
939
 
940
 
940
 
941
   /* this updates the visual's red/green/blue/alphaBits fields */
941
   /* this updates the visual's red/green/blue/alphaBits fields */
942
   _mesa_update_framebuffer_visual(&osmesa->mesa, osmesa->gl_buffer);
942
   _mesa_update_framebuffer_visual(&osmesa->mesa, osmesa->gl_buffer);
943
 
943
 
944
   /* update the framebuffer size */
944
   /* update the framebuffer size */
945
   _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
945
   _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height);
946
 
946
 
947
   return GL_TRUE;
947
   return GL_TRUE;
948
}
948
}
949
 
949
 
950
 
950
 
951
 
951
 
952
GLAPI OSMesaContext GLAPIENTRY
952
GLAPI OSMesaContext GLAPIENTRY
953
OSMesaGetCurrentContext( void )
953
OSMesaGetCurrentContext( void )
954
{
954
{
955
   struct gl_context *ctx = _mesa_get_current_context();
955
   struct gl_context *ctx = _mesa_get_current_context();
956
   if (ctx)
956
   if (ctx)
957
      return (OSMesaContext) ctx;
957
      return (OSMesaContext) ctx;
958
   else
958
   else
959
      return NULL;
959
      return NULL;
960
}
960
}
961
 
961
 
962
 
962
 
963
 
963
 
964
GLAPI void GLAPIENTRY
964
GLAPI void GLAPIENTRY
965
OSMesaPixelStore( GLint pname, GLint value )
965
OSMesaPixelStore( GLint pname, GLint value )
966
{
966
{
967
   OSMesaContext osmesa = OSMesaGetCurrentContext();
967
   OSMesaContext osmesa = OSMesaGetCurrentContext();
968
 
968
 
969
   switch (pname) {
969
   switch (pname) {
970
      case OSMESA_ROW_LENGTH:
970
      case OSMESA_ROW_LENGTH:
971
         if (value<0) {
971
         if (value<0) {
972
            _mesa_error( &osmesa->mesa, GL_INVALID_VALUE,
972
            _mesa_error( &osmesa->mesa, GL_INVALID_VALUE,
973
                      "OSMesaPixelStore(value)" );
973
                      "OSMesaPixelStore(value)" );
974
            return;
974
            return;
975
         }
975
         }
976
         osmesa->userRowLength = value;
976
         osmesa->userRowLength = value;
977
         break;
977
         break;
978
      case OSMESA_Y_UP:
978
      case OSMESA_Y_UP:
979
         osmesa->yup = value ? GL_TRUE : GL_FALSE;
979
         osmesa->yup = value ? GL_TRUE : GL_FALSE;
980
         break;
980
         break;
981
      default:
981
      default:
982
         _mesa_error( &osmesa->mesa, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
982
         _mesa_error( &osmesa->mesa, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" );
983
         return;
983
         return;
984
   }
984
   }
985
 
985
 
986
   compute_row_addresses( osmesa );
986
   compute_row_addresses( osmesa );
987
}
987
}
988
 
988
 
989
 
989
 
990
GLAPI void GLAPIENTRY
990
GLAPI void GLAPIENTRY
991
OSMesaGetIntegerv( GLint pname, GLint *value )
991
OSMesaGetIntegerv( GLint pname, GLint *value )
992
{
992
{
993
   OSMesaContext osmesa = OSMesaGetCurrentContext();
993
   OSMesaContext osmesa = OSMesaGetCurrentContext();
994
 
994
 
995
   switch (pname) {
995
   switch (pname) {
996
      case OSMESA_WIDTH:
996
      case OSMESA_WIDTH:
997
         if (osmesa->gl_buffer)
997
         if (osmesa->gl_buffer)
998
            *value = osmesa->gl_buffer->Width;
998
            *value = osmesa->gl_buffer->Width;
999
         else
999
         else
1000
            *value = 0;
1000
            *value = 0;
1001
         return;
1001
         return;
1002
      case OSMESA_HEIGHT:
1002
      case OSMESA_HEIGHT:
1003
         if (osmesa->gl_buffer)
1003
         if (osmesa->gl_buffer)
1004
            *value = osmesa->gl_buffer->Height;
1004
            *value = osmesa->gl_buffer->Height;
1005
         else
1005
         else
1006
            *value = 0;
1006
            *value = 0;
1007
         return;
1007
         return;
1008
      case OSMESA_FORMAT:
1008
      case OSMESA_FORMAT:
1009
         *value = osmesa->format;
1009
         *value = osmesa->format;
1010
         return;
1010
         return;
1011
      case OSMESA_TYPE:
1011
      case OSMESA_TYPE:
1012
         /* current color buffer's data type */
1012
         /* current color buffer's data type */
1013
         *value = osmesa->DataType;
1013
         *value = osmesa->DataType;
1014
         return;
1014
         return;
1015
      case OSMESA_ROW_LENGTH:
1015
      case OSMESA_ROW_LENGTH:
1016
         *value = osmesa->userRowLength;
1016
         *value = osmesa->userRowLength;
1017
         return;
1017
         return;
1018
      case OSMESA_Y_UP:
1018
      case OSMESA_Y_UP:
1019
         *value = osmesa->yup;
1019
         *value = osmesa->yup;
1020
         return;
1020
         return;
1021
      case OSMESA_MAX_WIDTH:
1021
      case OSMESA_MAX_WIDTH:
1022
         *value = SWRAST_MAX_WIDTH;
1022
         *value = SWRAST_MAX_WIDTH;
1023
         return;
1023
         return;
1024
      case OSMESA_MAX_HEIGHT:
1024
      case OSMESA_MAX_HEIGHT:
1025
         *value = SWRAST_MAX_HEIGHT;
1025
         *value = SWRAST_MAX_HEIGHT;
1026
         return;
1026
         return;
1027
      default:
1027
      default:
1028
         _mesa_error(&osmesa->mesa, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
1028
         _mesa_error(&osmesa->mesa, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)");
1029
         return;
1029
         return;
1030
   }
1030
   }
1031
}
1031
}
1032
 
1032
 
1033
 
1033
 
1034
/**
1034
/**
1035
 * Return the depth buffer associated with an OSMesa context.
1035
 * Return the depth buffer associated with an OSMesa context.
1036
 * Input:  c - the OSMesa context
1036
 * Input:  c - the OSMesa context
1037
 * Output:  width, height - size of buffer in pixels
1037
 * Output:  width, height - size of buffer in pixels
1038
 *          bytesPerValue - bytes per depth value (2 or 4)
1038
 *          bytesPerValue - bytes per depth value (2 or 4)
1039
 *          buffer - pointer to depth buffer values
1039
 *          buffer - pointer to depth buffer values
1040
 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
1040
 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
1041
 */
1041
 */
1042
GLAPI GLboolean GLAPIENTRY
1042
GLAPI GLboolean GLAPIENTRY
1043
OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
1043
OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height,
1044
                      GLint *bytesPerValue, void **buffer )
1044
                      GLint *bytesPerValue, void **buffer )
1045
{
1045
{
1046
   struct swrast_renderbuffer *srb = NULL;
1046
   struct swrast_renderbuffer *srb = NULL;
1047
 
1047
 
1048
   if (c->gl_buffer)
1048
   if (c->gl_buffer)
1049
      srb = swrast_renderbuffer(c->gl_buffer->
1049
      srb = swrast_renderbuffer(c->gl_buffer->
1050
                                Attachment[BUFFER_DEPTH].Renderbuffer);
1050
                                Attachment[BUFFER_DEPTH].Renderbuffer);
1051
 
1051
 
1052
   if (!srb || !srb->Buffer) {
1052
   if (!srb || !srb->Buffer) {
1053
      *width = 0;
1053
      *width = 0;
1054
      *height = 0;
1054
      *height = 0;
1055
      *bytesPerValue = 0;
1055
      *bytesPerValue = 0;
1056
      *buffer = 0;
1056
      *buffer = 0;
1057
      return GL_FALSE;
1057
      return GL_FALSE;
1058
   }
1058
   }
1059
   else {
1059
   else {
1060
      *width = srb->Base.Width;
1060
      *width = srb->Base.Width;
1061
      *height = srb->Base.Height;
1061
      *height = srb->Base.Height;
1062
      if (c->gl_visual->depthBits <= 16)
1062
      if (c->gl_visual->depthBits <= 16)
1063
         *bytesPerValue = sizeof(GLushort);
1063
         *bytesPerValue = sizeof(GLushort);
1064
      else
1064
      else
1065
         *bytesPerValue = sizeof(GLuint);
1065
         *bytesPerValue = sizeof(GLuint);
1066
      *buffer = (void *) srb->Buffer;
1066
      *buffer = (void *) srb->Buffer;
1067
      return GL_TRUE;
1067
      return GL_TRUE;
1068
   }
1068
   }
1069
}
1069
}
1070
 
1070
 
1071
 
1071
 
1072
/**
1072
/**
1073
 * Return the color buffer associated with an OSMesa context.
1073
 * Return the color buffer associated with an OSMesa context.
1074
 * Input:  c - the OSMesa context
1074
 * Input:  c - the OSMesa context
1075
 * Output:  width, height - size of buffer in pixels
1075
 * Output:  width, height - size of buffer in pixels
1076
 *          format - the pixel format (OSMESA_FORMAT)
1076
 *          format - the pixel format (OSMESA_FORMAT)
1077
 *          buffer - pointer to color buffer values
1077
 *          buffer - pointer to color buffer values
1078
 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
1078
 * Return:  GL_TRUE or GL_FALSE to indicate success or failure.
1079
 */
1079
 */
1080
GLAPI GLboolean GLAPIENTRY
1080
GLAPI GLboolean GLAPIENTRY
1081
OSMesaGetColorBuffer( OSMesaContext osmesa, GLint *width,
1081
OSMesaGetColorBuffer( OSMesaContext osmesa, GLint *width,
1082
                      GLint *height, GLint *format, void **buffer )
1082
                      GLint *height, GLint *format, void **buffer )
1083
{
1083
{
1084
   if (osmesa->srb && osmesa->srb->Buffer) {
1084
   if (osmesa->srb && osmesa->srb->Buffer) {
1085
      *width = osmesa->srb->Base.Width;
1085
      *width = osmesa->srb->Base.Width;
1086
      *height = osmesa->srb->Base.Height;
1086
      *height = osmesa->srb->Base.Height;
1087
      *format = osmesa->format;
1087
      *format = osmesa->format;
1088
      *buffer = (void *) osmesa->srb->Buffer;
1088
      *buffer = (void *) osmesa->srb->Buffer;
1089
      return GL_TRUE;
1089
      return GL_TRUE;
1090
   }
1090
   }
1091
   else {
1091
   else {
1092
      *width = 0;
1092
      *width = 0;
1093
      *height = 0;
1093
      *height = 0;
1094
      *format = 0;
1094
      *format = 0;
1095
      *buffer = 0;
1095
      *buffer = 0;
1096
      return GL_FALSE;
1096
      return GL_FALSE;
1097
   }
1097
   }
1098
}
1098
}
1099
 
1099
 
1100
 
1100
 
1101
struct name_function
1101
struct name_function
1102
{
1102
{
1103
   const char *Name;
1103
   const char *Name;
1104
   OSMESAproc Function;
1104
   OSMESAproc Function;
1105
};
1105
};
1106
 
1106
 
1107
static struct name_function functions[] = {
1107
static struct name_function functions[] = {
1108
   { "OSMesaCreateContext", (OSMESAproc) OSMesaCreateContext },
1108
   { "OSMesaCreateContext", (OSMESAproc) OSMesaCreateContext },
1109
   { "OSMesaCreateContextExt", (OSMESAproc) OSMesaCreateContextExt },
1109
   { "OSMesaCreateContextExt", (OSMESAproc) OSMesaCreateContextExt },
1110
   { "OSMesaDestroyContext", (OSMESAproc) OSMesaDestroyContext },
1110
   { "OSMesaDestroyContext", (OSMESAproc) OSMesaDestroyContext },
1111
   { "OSMesaMakeCurrent", (OSMESAproc) OSMesaMakeCurrent },
1111
   { "OSMesaMakeCurrent", (OSMESAproc) OSMesaMakeCurrent },
1112
   { "OSMesaGetCurrentContext", (OSMESAproc) OSMesaGetCurrentContext },
1112
   { "OSMesaGetCurrentContext", (OSMESAproc) OSMesaGetCurrentContext },
1113
   { "OSMesaPixelsStore", (OSMESAproc) OSMesaPixelStore },
1113
   { "OSMesaPixelsStore", (OSMESAproc) OSMesaPixelStore },
1114
   { "OSMesaGetIntegerv", (OSMESAproc) OSMesaGetIntegerv },
1114
   { "OSMesaGetIntegerv", (OSMESAproc) OSMesaGetIntegerv },
1115
   { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer },
1115
   { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer },
1116
   { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer },
1116
   { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer },
1117
   { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress },
1117
   { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress },
1118
   { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp },
1118
   { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp },
1119
   { NULL, NULL }
1119
   { NULL, NULL }
1120
};
1120
};
1121
 
1121
 
1122
 
1122
 
1123
GLAPI OSMESAproc GLAPIENTRY
1123
GLAPI OSMESAproc GLAPIENTRY
1124
OSMesaGetProcAddress( const char *funcName )
1124
OSMesaGetProcAddress( const char *funcName )
1125
{
1125
{
1126
   int i;
1126
   int i;
1127
   for (i = 0; functions[i].Name; i++) {
1127
   for (i = 0; functions[i].Name; i++) {
1128
      if (strcmp(functions[i].Name, funcName) == 0)
1128
      if (strcmp(functions[i].Name, funcName) == 0)
1129
         return functions[i].Function;
1129
         return functions[i].Function;
1130
   }
1130
   }
1131
   return _glapi_get_proc_address(funcName);
1131
   return _glapi_get_proc_address(funcName);
1132
}
1132
}
1133
 
1133
 
1134
 
1134
 
1135
GLAPI void GLAPIENTRY
1135
GLAPI void GLAPIENTRY
1136
OSMesaColorClamp(GLboolean enable)
1136
OSMesaColorClamp(GLboolean enable)
1137
{
1137
{
1138
   OSMesaContext osmesa = OSMesaGetCurrentContext();
1138
   OSMesaContext osmesa = OSMesaGetCurrentContext();
1139
 
1139
 
1140
   if (enable == GL_TRUE) {
1140
   if (enable == GL_TRUE) {
1141
      osmesa->mesa.Color.ClampFragmentColor = GL_TRUE;
1141
      osmesa->mesa.Color.ClampFragmentColor = GL_TRUE;
1142
   }
1142
   }
1143
   else {
1143
   else {
1144
      osmesa->mesa.Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
1144
      osmesa->mesa.Color.ClampFragmentColor = GL_FIXED_ONLY_ARB;
1145
   }
1145
   }
1146
}
1146
}
1147
 
1147
 
1148
 
1148
 
1149
/**
1149
/**
1150
 * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in
1150
 * When GLX_INDIRECT_RENDERING is defined, some symbols are missing in
1151
 * libglapi.a.  We need to define them here.
1151
 * libglapi.a.  We need to define them here.
1152
 */
1152
 */
1153
#ifdef GLX_INDIRECT_RENDERING
1153
#ifdef GLX_INDIRECT_RENDERING
1154
 
1154
 
1155
#define GL_GLEXT_PROTOTYPES
1155
#define GL_GLEXT_PROTOTYPES
1156
#include "GL/gl.h"
1156
#include "GL/gl.h"
1157
#include "glapi/glapi.h"
1157
#include "glapi/glapi.h"
1158
#include "glapi/glapitable.h"
1158
#include "glapi/glapitable.h"
1159
 
1159
 
1160
#if defined(USE_MGL_NAMESPACE)
1160
#if defined(USE_MGL_NAMESPACE)
1161
#define NAME(func)  mgl##func
1161
#define NAME(func)  mgl##func
1162
#else
1162
#else
1163
#define NAME(func)  gl##func
1163
#define NAME(func)  gl##func
1164
#endif
1164
#endif
1165
 
1165
 
1166
#define DISPATCH(FUNC, ARGS, MESSAGE)		\
1166
#define DISPATCH(FUNC, ARGS, MESSAGE)		\
1167
   GET_DISPATCH()->FUNC ARGS
1167
   GET_DISPATCH()->FUNC ARGS
1168
 
1168
 
1169
#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) 	\
1169
#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) 	\
1170
   return GET_DISPATCH()->FUNC ARGS
1170
   return GET_DISPATCH()->FUNC ARGS
1171
 
1171
 
1172
/* skip normal ones */
1172
/* skip normal ones */
1173
#define _GLAPI_SKIP_NORMAL_ENTRY_POINTS
1173
#define _GLAPI_SKIP_NORMAL_ENTRY_POINTS
1174
#include "glapi/glapitemp.h"
1174
#include "glapi/glapitemp.h"
1175
 
1175
 
1176
#endif /* GLX_INDIRECT_RENDERING */
1176
#endif /* GLX_INDIRECT_RENDERING */
1177
 
-
 
1178
int atexit(void (*func)(void))
-
 
1179
{
-
 
1180
    return 0;
-
 
1181
};
-
 
1182
>
1177
>