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 */=>0)>>>1, |
1177 | - | ||
1178 | int atexit(void (*func)(void)) |
- | |
1179 | { |
- | |
1180 | return 0; |
- | |
1181 | };=>0)>>>1, |
- | |
1182 | >1,>>>>>>>>>>>>>>>>>> |
1177 | >1,>>>>>>>>>>>>>>>>>> |