Rev 1901 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1901 | serge | 1 | /* |
2 | * Mesa 3-D graphics library |
||
3 | * Version: 6.5.3 |
||
4 | * |
||
5 | * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. |
||
6 | * |
||
7 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
8 | * copy of this software and associated documentation files (the "Software"), |
||
9 | * to deal in the Software without restriction, including without limitation |
||
10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
11 | * and/or sell copies of the Software, and to permit persons to whom the |
||
12 | * Software is furnished to do so, subject to the following conditions: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice shall be included |
||
15 | * in all copies or substantial portions of the Software. |
||
16 | * |
||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
20 | * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
||
21 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
||
22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
23 | */ |
||
24 | |||
25 | |||
26 | /* |
||
27 | * Off-Screen Mesa rendering / Rendering into client memory space |
||
28 | * |
||
29 | * Note on thread safety: this driver is thread safe. All |
||
30 | * functions are reentrant. The notion of current context is |
||
31 | * managed by the core _mesa_make_current() and _mesa_get_current_context() |
||
32 | * functions. Those functions are thread-safe. |
||
33 | */ |
||
34 | |||
35 | |||
36 | #include "main/glheader.h" |
||
37 | #include "GL/osmesa.h" |
||
38 | #include "main/context.h" |
||
39 | #include "main/extensions.h" |
||
40 | #include "main/formats.h" |
||
41 | #include "main/framebuffer.h" |
||
42 | #include "main/imports.h" |
||
43 | #include "main/mtypes.h" |
||
44 | #include "main/renderbuffer.h" |
||
45 | #include "swrast/swrast.h" |
||
46 | #include "swrast_setup/swrast_setup.h" |
||
47 | #include "swrast/s_context.h" |
||
48 | #include "swrast/s_lines.h" |
||
49 | #include "swrast/s_triangle.h" |
||
50 | #include "tnl/tnl.h" |
||
51 | #include "tnl/t_context.h" |
||
52 | #include "tnl/t_pipeline.h" |
||
53 | #include "drivers/common/driverfuncs.h" |
||
54 | #include "drivers/common/meta.h" |
||
55 | #include "vbo/vbo.h" |
||
56 | |||
57 | |||
58 | |||
59 | /** |
||
60 | * OSMesa rendering context, derived from core Mesa struct gl_context. |
||
61 | */ |
||
62 | struct osmesa_context |
||
63 | { |
||
64 | struct gl_context mesa; /*< Base class - this must be first */ |
||
65 | struct gl_config *gl_visual; /*< Describes the buffers */ |
||
66 | struct gl_renderbuffer *rb; /*< The user's colorbuffer */ |
||
67 | struct gl_framebuffer *gl_buffer; /*< The framebuffer, containing user's rb */ |
||
68 | GLenum format; /*< User-specified context format */ |
||
69 | GLint userRowLength; /*< user-specified number of pixels per row */ |
||
70 | GLint rInd, gInd, bInd, aInd;/*< index offsets for RGBA formats */ |
||
71 | GLvoid *rowaddr[MAX_HEIGHT]; /*< address of first pixel in each image row */ |
||
72 | GLboolean yup; /*< TRUE -> Y increases upward */ |
||
73 | /*< FALSE -> Y increases downward */ |
||
74 | }; |
||
75 | |||
76 | |||
77 | static INLINE OSMesaContext |
||
78 | OSMESA_CONTEXT(struct gl_context *ctx) |
||
79 | { |
||
80 | /* Just cast, since we're using structure containment */ |
||
81 | return (OSMesaContext) ctx; |
||
82 | } |
||
83 | |||
84 | |||
85 | /**********************************************************************/ |
||
86 | /*** Private Device Driver Functions ***/ |
||
87 | /**********************************************************************/ |
||
88 | |||
89 | |||
90 | static const GLubyte * |
||
91 | get_string( struct gl_context *ctx, GLenum name ) |
||
92 | { |
||
93 | (void) ctx; |
||
94 | switch (name) { |
||
95 | case GL_RENDERER: |
||
96 | #if CHAN_BITS == 32 |
||
97 | return (const GLubyte *) "Mesa OffScreen32"; |
||
98 | #elif CHAN_BITS == 16 |
||
99 | return (const GLubyte *) "Mesa OffScreen16"; |
||
100 | #else |
||
101 | return (const GLubyte *) "Mesa OffScreen"; |
||
102 | #endif |
||
103 | default: |
||
104 | return NULL; |
||
105 | } |
||
106 | } |
||
107 | |||
108 | |||
109 | static void |
||
110 | osmesa_update_state( struct gl_context *ctx, GLuint new_state ) |
||
111 | { |
||
112 | /* easy - just propogate */ |
||
113 | _swrast_InvalidateState( ctx, new_state ); |
||
114 | _swsetup_InvalidateState( ctx, new_state ); |
||
115 | _tnl_InvalidateState( ctx, new_state ); |
||
116 | _vbo_InvalidateState( ctx, new_state ); |
||
117 | } |
||
118 | |||
119 | |||
120 | |||
121 | /**********************************************************************/ |
||
122 | /***** Read/write spans/arrays of pixels *****/ |
||
123 | /**********************************************************************/ |
||
124 | |||
125 | /* 8-bit RGBA */ |
||
126 | #define NAME(PREFIX) PREFIX##_RGBA8 |
||
127 | #define RB_TYPE GLubyte |
||
128 | #define SPAN_VARS \ |
||
129 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
130 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
131 | GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X) |
||
132 | #define INC_PIXEL_PTR(P) P += 4 |
||
133 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
134 | DST[0] = VALUE[RCOMP]; \ |
||
135 | DST[1] = VALUE[GCOMP]; \ |
||
136 | DST[2] = VALUE[BCOMP]; \ |
||
137 | DST[3] = VALUE[ACOMP] |
||
138 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
139 | DST[0] = VALUE[RCOMP]; \ |
||
140 | DST[1] = VALUE[GCOMP]; \ |
||
141 | DST[2] = VALUE[BCOMP]; \ |
||
142 | DST[3] = 255 |
||
143 | #define FETCH_PIXEL(DST, SRC) \ |
||
144 | DST[RCOMP] = SRC[0]; \ |
||
145 | DST[GCOMP] = SRC[1]; \ |
||
146 | DST[BCOMP] = SRC[2]; \ |
||
147 | DST[ACOMP] = SRC[3] |
||
148 | #include "swrast/s_spantemp.h" |
||
149 | |||
150 | /* 16-bit RGBA */ |
||
151 | #define NAME(PREFIX) PREFIX##_RGBA16 |
||
152 | #define RB_TYPE GLushort |
||
153 | #define SPAN_VARS \ |
||
154 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
155 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
156 | GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X) |
||
157 | #define INC_PIXEL_PTR(P) P += 4 |
||
158 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
159 | DST[0] = VALUE[RCOMP]; \ |
||
160 | DST[1] = VALUE[GCOMP]; \ |
||
161 | DST[2] = VALUE[BCOMP]; \ |
||
162 | DST[3] = VALUE[ACOMP] |
||
163 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
164 | DST[0] = VALUE[RCOMP]; \ |
||
165 | DST[1] = VALUE[GCOMP]; \ |
||
166 | DST[2] = VALUE[BCOMP]; \ |
||
167 | DST[3] = 65535 |
||
168 | #define FETCH_PIXEL(DST, SRC) \ |
||
169 | DST[RCOMP] = SRC[0]; \ |
||
170 | DST[GCOMP] = SRC[1]; \ |
||
171 | DST[BCOMP] = SRC[2]; \ |
||
172 | DST[ACOMP] = SRC[3] |
||
173 | #include "swrast/s_spantemp.h" |
||
174 | |||
175 | /* 32-bit RGBA */ |
||
176 | #define NAME(PREFIX) PREFIX##_RGBA32 |
||
177 | #define RB_TYPE GLfloat |
||
178 | #define SPAN_VARS \ |
||
179 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
180 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
181 | GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X) |
||
182 | #define INC_PIXEL_PTR(P) P += 4 |
||
183 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
184 | DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \ |
||
185 | DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \ |
||
186 | DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \ |
||
187 | DST[3] = CLAMP((VALUE[ACOMP]), 0.0F, 1.0F) |
||
188 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
189 | DST[0] = MAX2((VALUE[RCOMP]), 0.0F); \ |
||
190 | DST[1] = MAX2((VALUE[GCOMP]), 0.0F); \ |
||
191 | DST[2] = MAX2((VALUE[BCOMP]), 0.0F); \ |
||
192 | DST[3] = 1.0F |
||
193 | #define FETCH_PIXEL(DST, SRC) \ |
||
194 | DST[RCOMP] = SRC[0]; \ |
||
195 | DST[GCOMP] = SRC[1]; \ |
||
196 | DST[BCOMP] = SRC[2]; \ |
||
197 | DST[ACOMP] = SRC[3] |
||
198 | #include "swrast/s_spantemp.h" |
||
199 | |||
200 | |||
201 | /* 8-bit BGRA */ |
||
202 | #define NAME(PREFIX) PREFIX##_BGRA8 |
||
203 | #define RB_TYPE GLubyte |
||
204 | #define SPAN_VARS \ |
||
205 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
206 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
207 | GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X) |
||
208 | #define INC_PIXEL_PTR(P) P += 4 |
||
209 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
210 | DST[2] = VALUE[RCOMP]; \ |
||
211 | DST[1] = VALUE[GCOMP]; \ |
||
212 | DST[0] = VALUE[BCOMP]; \ |
||
213 | DST[3] = VALUE[ACOMP] |
||
214 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
215 | DST[2] = VALUE[RCOMP]; \ |
||
216 | DST[1] = VALUE[GCOMP]; \ |
||
217 | DST[0] = VALUE[BCOMP]; \ |
||
218 | DST[3] = 255 |
||
219 | #define FETCH_PIXEL(DST, SRC) \ |
||
220 | DST[RCOMP] = SRC[2]; \ |
||
221 | DST[GCOMP] = SRC[1]; \ |
||
222 | DST[BCOMP] = SRC[0]; \ |
||
223 | DST[ACOMP] = SRC[3] |
||
224 | #include "swrast/s_spantemp.h" |
||
225 | |||
226 | /* 16-bit BGRA */ |
||
227 | #define NAME(PREFIX) PREFIX##_BGRA16 |
||
228 | #define RB_TYPE GLushort |
||
229 | #define SPAN_VARS \ |
||
230 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
231 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
232 | GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X) |
||
233 | #define INC_PIXEL_PTR(P) P += 4 |
||
234 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
235 | DST[2] = VALUE[RCOMP]; \ |
||
236 | DST[1] = VALUE[GCOMP]; \ |
||
237 | DST[0] = VALUE[BCOMP]; \ |
||
238 | DST[3] = VALUE[ACOMP] |
||
239 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
240 | DST[2] = VALUE[RCOMP]; \ |
||
241 | DST[1] = VALUE[GCOMP]; \ |
||
242 | DST[0] = VALUE[BCOMP]; \ |
||
243 | DST[3] = 65535 |
||
244 | #define FETCH_PIXEL(DST, SRC) \ |
||
245 | DST[RCOMP] = SRC[2]; \ |
||
246 | DST[GCOMP] = SRC[1]; \ |
||
247 | DST[BCOMP] = SRC[0]; \ |
||
248 | DST[ACOMP] = SRC[3] |
||
249 | #include "swrast/s_spantemp.h" |
||
250 | |||
251 | /* 32-bit BGRA */ |
||
252 | #define NAME(PREFIX) PREFIX##_BGRA32 |
||
253 | #define RB_TYPE GLfloat |
||
254 | #define SPAN_VARS \ |
||
255 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
256 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
257 | GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X) |
||
258 | #define INC_PIXEL_PTR(P) P += 4 |
||
259 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
260 | DST[2] = VALUE[RCOMP]; \ |
||
261 | DST[1] = VALUE[GCOMP]; \ |
||
262 | DST[0] = VALUE[BCOMP]; \ |
||
263 | DST[3] = VALUE[ACOMP] |
||
264 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
265 | DST[2] = VALUE[RCOMP]; \ |
||
266 | DST[1] = VALUE[GCOMP]; \ |
||
267 | DST[0] = VALUE[BCOMP]; \ |
||
268 | DST[3] = 1.0F |
||
269 | #define FETCH_PIXEL(DST, SRC) \ |
||
270 | DST[RCOMP] = SRC[2]; \ |
||
271 | DST[GCOMP] = SRC[1]; \ |
||
272 | DST[BCOMP] = SRC[0]; \ |
||
273 | DST[ACOMP] = SRC[3] |
||
274 | #include "swrast/s_spantemp.h" |
||
275 | |||
276 | |||
277 | /* 8-bit ARGB */ |
||
278 | #define NAME(PREFIX) PREFIX##_ARGB8 |
||
279 | #define RB_TYPE GLubyte |
||
280 | #define SPAN_VARS \ |
||
281 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
282 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
283 | GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 4 * (X) |
||
284 | #define INC_PIXEL_PTR(P) P += 4 |
||
285 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
286 | DST[1] = VALUE[RCOMP]; \ |
||
287 | DST[2] = VALUE[GCOMP]; \ |
||
288 | DST[3] = VALUE[BCOMP]; \ |
||
289 | DST[0] = VALUE[ACOMP] |
||
290 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
291 | DST[1] = VALUE[RCOMP]; \ |
||
292 | DST[2] = VALUE[GCOMP]; \ |
||
293 | DST[3] = VALUE[BCOMP]; \ |
||
294 | DST[0] = 255 |
||
295 | #define FETCH_PIXEL(DST, SRC) \ |
||
296 | DST[RCOMP] = SRC[1]; \ |
||
297 | DST[GCOMP] = SRC[2]; \ |
||
298 | DST[BCOMP] = SRC[3]; \ |
||
299 | DST[ACOMP] = SRC[0] |
||
300 | #include "swrast/s_spantemp.h" |
||
301 | |||
302 | /* 16-bit ARGB */ |
||
303 | #define NAME(PREFIX) PREFIX##_ARGB16 |
||
304 | #define RB_TYPE GLushort |
||
305 | #define SPAN_VARS \ |
||
306 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
307 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
308 | GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 4 * (X) |
||
309 | #define INC_PIXEL_PTR(P) P += 4 |
||
310 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
311 | DST[1] = VALUE[RCOMP]; \ |
||
312 | DST[2] = VALUE[GCOMP]; \ |
||
313 | DST[3] = VALUE[BCOMP]; \ |
||
314 | DST[0] = VALUE[ACOMP] |
||
315 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
316 | DST[1] = VALUE[RCOMP]; \ |
||
317 | DST[2] = VALUE[GCOMP]; \ |
||
318 | DST[3] = VALUE[BCOMP]; \ |
||
319 | DST[0] = 65535 |
||
320 | #define FETCH_PIXEL(DST, SRC) \ |
||
321 | DST[RCOMP] = SRC[1]; \ |
||
322 | DST[GCOMP] = SRC[2]; \ |
||
323 | DST[BCOMP] = SRC[3]; \ |
||
324 | DST[ACOMP] = SRC[0] |
||
325 | #include "swrast/s_spantemp.h" |
||
326 | |||
327 | /* 32-bit ARGB */ |
||
328 | #define NAME(PREFIX) PREFIX##_ARGB32 |
||
329 | #define RB_TYPE GLfloat |
||
330 | #define SPAN_VARS \ |
||
331 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
332 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
333 | GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 4 * (X) |
||
334 | #define INC_PIXEL_PTR(P) P += 4 |
||
335 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
336 | DST[1] = VALUE[RCOMP]; \ |
||
337 | DST[2] = VALUE[GCOMP]; \ |
||
338 | DST[3] = VALUE[BCOMP]; \ |
||
339 | DST[0] = VALUE[ACOMP] |
||
340 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ |
||
341 | DST[1] = VALUE[RCOMP]; \ |
||
342 | DST[2] = VALUE[GCOMP]; \ |
||
343 | DST[3] = VALUE[BCOMP]; \ |
||
344 | DST[0] = 1.0F |
||
345 | #define FETCH_PIXEL(DST, SRC) \ |
||
346 | DST[RCOMP] = SRC[1]; \ |
||
347 | DST[GCOMP] = SRC[2]; \ |
||
348 | DST[BCOMP] = SRC[3]; \ |
||
349 | DST[ACOMP] = SRC[0] |
||
350 | #include "swrast/s_spantemp.h" |
||
351 | |||
352 | |||
353 | /* 8-bit RGB */ |
||
354 | #define NAME(PREFIX) PREFIX##_RGB8 |
||
355 | #define RB_TYPE GLubyte |
||
356 | #define SPAN_VARS \ |
||
357 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
358 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
359 | GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 3 * (X) |
||
360 | #define INC_PIXEL_PTR(P) P += 3 |
||
361 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
362 | DST[0] = VALUE[RCOMP]; \ |
||
363 | DST[1] = VALUE[GCOMP]; \ |
||
364 | DST[2] = VALUE[BCOMP] |
||
365 | #define FETCH_PIXEL(DST, SRC) \ |
||
366 | DST[RCOMP] = SRC[0]; \ |
||
367 | DST[GCOMP] = SRC[1]; \ |
||
368 | DST[BCOMP] = SRC[2]; \ |
||
369 | DST[ACOMP] = 255 |
||
370 | #include "swrast/s_spantemp.h" |
||
371 | |||
372 | /* 16-bit RGB */ |
||
373 | #define NAME(PREFIX) PREFIX##_RGB16 |
||
374 | #define RB_TYPE GLushort |
||
375 | #define SPAN_VARS \ |
||
376 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
377 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
378 | GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 3 * (X) |
||
379 | #define INC_PIXEL_PTR(P) P += 3 |
||
380 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
381 | DST[0] = VALUE[RCOMP]; \ |
||
382 | DST[1] = VALUE[GCOMP]; \ |
||
383 | DST[2] = VALUE[BCOMP] |
||
384 | #define FETCH_PIXEL(DST, SRC) \ |
||
385 | DST[RCOMP] = SRC[0]; \ |
||
386 | DST[GCOMP] = SRC[1]; \ |
||
387 | DST[BCOMP] = SRC[2]; \ |
||
388 | DST[ACOMP] = 65535U |
||
389 | #include "swrast/s_spantemp.h" |
||
390 | |||
391 | /* 32-bit RGB */ |
||
392 | #define NAME(PREFIX) PREFIX##_RGB32 |
||
393 | #define RB_TYPE GLfloat |
||
394 | #define SPAN_VARS \ |
||
395 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
396 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
397 | GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 3 * (X) |
||
398 | #define INC_PIXEL_PTR(P) P += 3 |
||
399 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
400 | DST[0] = VALUE[RCOMP]; \ |
||
401 | DST[1] = VALUE[GCOMP]; \ |
||
402 | DST[2] = VALUE[BCOMP] |
||
403 | #define FETCH_PIXEL(DST, SRC) \ |
||
404 | DST[RCOMP] = SRC[0]; \ |
||
405 | DST[GCOMP] = SRC[1]; \ |
||
406 | DST[BCOMP] = SRC[2]; \ |
||
407 | DST[ACOMP] = 1.0F |
||
408 | #include "swrast/s_spantemp.h" |
||
409 | |||
410 | |||
411 | /* 8-bit BGR */ |
||
412 | #define NAME(PREFIX) PREFIX##_BGR8 |
||
413 | #define RB_TYPE GLubyte |
||
414 | #define SPAN_VARS \ |
||
415 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
416 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
417 | GLubyte *P = (GLubyte *) osmesa->rowaddr[Y] + 3 * (X) |
||
418 | #define INC_PIXEL_PTR(P) P += 3 |
||
419 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
420 | DST[2] = VALUE[RCOMP]; \ |
||
421 | DST[1] = VALUE[GCOMP]; \ |
||
422 | DST[0] = VALUE[BCOMP] |
||
423 | #define FETCH_PIXEL(DST, SRC) \ |
||
424 | DST[RCOMP] = SRC[2]; \ |
||
425 | DST[GCOMP] = SRC[1]; \ |
||
426 | DST[BCOMP] = SRC[0]; \ |
||
427 | DST[ACOMP] = 255 |
||
428 | #include "swrast/s_spantemp.h" |
||
429 | |||
430 | /* 16-bit BGR */ |
||
431 | #define NAME(PREFIX) PREFIX##_BGR16 |
||
432 | #define RB_TYPE GLushort |
||
433 | #define SPAN_VARS \ |
||
434 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
435 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
436 | GLushort *P = (GLushort *) osmesa->rowaddr[Y] + 3 * (X) |
||
437 | #define INC_PIXEL_PTR(P) P += 3 |
||
438 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
439 | DST[2] = VALUE[RCOMP]; \ |
||
440 | DST[1] = VALUE[GCOMP]; \ |
||
441 | DST[0] = VALUE[BCOMP] |
||
442 | #define FETCH_PIXEL(DST, SRC) \ |
||
443 | DST[RCOMP] = SRC[2]; \ |
||
444 | DST[GCOMP] = SRC[1]; \ |
||
445 | DST[BCOMP] = SRC[0]; \ |
||
446 | DST[ACOMP] = 65535 |
||
447 | #include "swrast/s_spantemp.h" |
||
448 | |||
449 | /* 32-bit BGR */ |
||
450 | #define NAME(PREFIX) PREFIX##_BGR32 |
||
451 | #define RB_TYPE GLfloat |
||
452 | #define SPAN_VARS \ |
||
453 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
454 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
455 | GLfloat *P = (GLfloat *) osmesa->rowaddr[Y] + 3 * (X) |
||
456 | #define INC_PIXEL_PTR(P) P += 3 |
||
457 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
458 | DST[2] = VALUE[RCOMP]; \ |
||
459 | DST[1] = VALUE[GCOMP]; \ |
||
460 | DST[0] = VALUE[BCOMP] |
||
461 | #define FETCH_PIXEL(DST, SRC) \ |
||
462 | DST[RCOMP] = SRC[2]; \ |
||
463 | DST[GCOMP] = SRC[1]; \ |
||
464 | DST[BCOMP] = SRC[0]; \ |
||
465 | DST[ACOMP] = 1.0F |
||
466 | #include "swrast/s_spantemp.h" |
||
467 | |||
468 | |||
469 | /* 16-bit 5/6/5 RGB */ |
||
470 | #define NAME(PREFIX) PREFIX##_RGB_565 |
||
471 | #define RB_TYPE GLubyte |
||
472 | #define SPAN_VARS \ |
||
473 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
474 | #define INIT_PIXEL_PTR(P, X, Y) \ |
||
475 | GLushort *P = (GLushort *) osmesa->rowaddr[Y] + (X) |
||
476 | #define INC_PIXEL_PTR(P) P += 1 |
||
477 | #define STORE_PIXEL(DST, X, Y, VALUE) \ |
||
478 | *DST = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) ) |
||
479 | #define FETCH_PIXEL(DST, SRC) \ |
||
480 | DST[RCOMP] = ( (((*SRC) >> 8) & 0xf8) | (((*SRC) >> 11) & 0x7) ); \ |
||
481 | DST[GCOMP] = ( (((*SRC) >> 3) & 0xfc) | (((*SRC) >> 5) & 0x3) ); \ |
||
482 | DST[BCOMP] = ( (((*SRC) << 3) & 0xf8) | (((*SRC) ) & 0x7) ); \ |
||
483 | DST[ACOMP] = CHAN_MAX |
||
484 | #include "swrast/s_spantemp.h" |
||
485 | |||
486 | |||
487 | /** |
||
488 | * Macros for optimized line/triangle rendering. |
||
489 | * Only for 8-bit channel, RGBA, BGRA, ARGB formats. |
||
490 | */ |
||
491 | |||
492 | #define PACK_RGBA(DST, R, G, B, A) \ |
||
493 | do { \ |
||
494 | (DST)[osmesa->rInd] = R; \ |
||
495 | (DST)[osmesa->gInd] = G; \ |
||
496 | (DST)[osmesa->bInd] = B; \ |
||
497 | (DST)[osmesa->aInd] = A; \ |
||
498 | } while (0) |
||
499 | |||
500 | #define PIXELADDR4(X,Y) ((GLchan *) osmesa->rowaddr[Y] + 4 * (X)) |
||
501 | |||
502 | |||
503 | /** |
||
504 | * Draw a flat-shaded, RGB line into an osmesa buffer. |
||
505 | */ |
||
506 | #define NAME flat_rgba_line |
||
507 | #define CLIP_HACK 1 |
||
508 | #define SETUP_CODE \ |
||
509 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); \ |
||
510 | const GLchan *color = vert1->color; |
||
511 | |||
512 | #define PLOT(X, Y) \ |
||
513 | do { \ |
||
514 | GLchan *p = PIXELADDR4(X, Y); \ |
||
515 | PACK_RGBA(p, color[0], color[1], color[2], color[3]); \ |
||
516 | } while (0) |
||
517 | |||
518 | #ifdef WIN32 |
||
519 | #include "..\swrast\s_linetemp.h" |
||
520 | #else |
||
521 | #include "swrast/s_linetemp.h" |
||
522 | #endif |
||
523 | |||
524 | |||
525 | |||
526 | /** |
||
527 | * Draw a flat-shaded, Z-less, RGB line into an osmesa buffer. |
||
528 | */ |
||
529 | #define NAME flat_rgba_z_line |
||
530 | #define CLIP_HACK 1 |
||
531 | #define INTERP_Z 1 |
||
532 | #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE |
||
533 | #define SETUP_CODE \ |
||
534 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); \ |
||
535 | const GLchan *color = vert1->color; |
||
536 | |||
537 | #define PLOT(X, Y) \ |
||
538 | do { \ |
||
539 | if (Z < *zPtr) { \ |
||
540 | GLchan *p = PIXELADDR4(X, Y); \ |
||
541 | PACK_RGBA(p, color[RCOMP], color[GCOMP], \ |
||
542 | color[BCOMP], color[ACOMP]); \ |
||
543 | *zPtr = Z; \ |
||
544 | } \ |
||
545 | } while (0) |
||
546 | |||
547 | #ifdef WIN32 |
||
548 | #include "..\swrast\s_linetemp.h" |
||
549 | #else |
||
550 | #include "swrast/s_linetemp.h" |
||
551 | #endif |
||
552 | |||
553 | |||
554 | |||
555 | /** |
||
556 | * Analyze context state to see if we can provide a fast line drawing |
||
557 | * function. Otherwise, return NULL. |
||
558 | */ |
||
559 | static swrast_line_func |
||
560 | osmesa_choose_line_function( struct gl_context *ctx ) |
||
561 | { |
||
562 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
563 | const SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
564 | |||
565 | if (osmesa->rb->DataType != GL_UNSIGNED_BYTE) |
||
566 | return NULL; |
||
567 | |||
568 | if (ctx->RenderMode != GL_RENDER) return NULL; |
||
569 | if (ctx->Line.SmoothFlag) return NULL; |
||
570 | if (ctx->Texture._EnabledUnits) return NULL; |
||
571 | if (ctx->Light.ShadeModel != GL_FLAT) return NULL; |
||
572 | if (ctx->Line.Width != 1.0F) return NULL; |
||
573 | if (ctx->Line.StippleFlag) return NULL; |
||
574 | if (ctx->Line.SmoothFlag) return NULL; |
||
575 | if (osmesa->format != OSMESA_RGBA && |
||
576 | osmesa->format != OSMESA_BGRA && |
||
577 | osmesa->format != OSMESA_ARGB) return NULL; |
||
578 | |||
579 | if (swrast->_RasterMask==DEPTH_BIT |
||
580 | && ctx->Depth.Func==GL_LESS |
||
581 | && ctx->Depth.Mask==GL_TRUE |
||
582 | && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { |
||
583 | return (swrast_line_func) flat_rgba_z_line; |
||
584 | } |
||
585 | |||
586 | if (swrast->_RasterMask == 0) { |
||
587 | return (swrast_line_func) flat_rgba_line; |
||
588 | } |
||
589 | |||
590 | return (swrast_line_func) NULL; |
||
591 | } |
||
592 | |||
593 | |||
594 | /**********************************************************************/ |
||
595 | /***** Optimized triangle rendering *****/ |
||
596 | /**********************************************************************/ |
||
597 | |||
598 | |||
599 | /* |
||
600 | * Smooth-shaded, z-less triangle, RGBA color. |
||
601 | */ |
||
602 | #define NAME smooth_rgba_z_triangle |
||
603 | #define INTERP_Z 1 |
||
604 | #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE |
||
605 | #define INTERP_RGB 1 |
||
606 | #define INTERP_ALPHA 1 |
||
607 | #define SETUP_CODE \ |
||
608 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
609 | #define RENDER_SPAN( span ) { \ |
||
610 | GLuint i; \ |
||
611 | GLchan *img = PIXELADDR4(span.x, span.y); \ |
||
612 | for (i = 0; i < span.end; i++, img += 4) { \ |
||
613 | const GLuint z = FixedToDepth(span.z); \ |
||
614 | if (z < zRow[i]) { \ |
||
615 | PACK_RGBA(img, FixedToChan(span.red), \ |
||
616 | FixedToChan(span.green), FixedToChan(span.blue), \ |
||
617 | FixedToChan(span.alpha)); \ |
||
618 | zRow[i] = z; \ |
||
619 | } \ |
||
620 | span.red += span.redStep; \ |
||
621 | span.green += span.greenStep; \ |
||
622 | span.blue += span.blueStep; \ |
||
623 | span.alpha += span.alphaStep; \ |
||
624 | span.z += span.zStep; \ |
||
625 | } \ |
||
626 | } |
||
627 | #ifdef WIN32 |
||
628 | #include "..\swrast\s_tritemp.h" |
||
629 | #else |
||
630 | #include "swrast/s_tritemp.h" |
||
631 | #endif |
||
632 | |||
633 | |||
634 | |||
635 | /* |
||
636 | * Flat-shaded, z-less triangle, RGBA color. |
||
637 | */ |
||
638 | #define NAME flat_rgba_z_triangle |
||
639 | #define INTERP_Z 1 |
||
640 | #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE |
||
641 | #define SETUP_CODE \ |
||
642 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); \ |
||
643 | GLuint pixel; \ |
||
644 | PACK_RGBA((GLchan *) &pixel, v2->color[0], v2->color[1], \ |
||
645 | v2->color[2], v2->color[3]); |
||
646 | |||
647 | #define RENDER_SPAN( span ) { \ |
||
648 | GLuint i; \ |
||
649 | GLuint *img = (GLuint *) PIXELADDR4(span.x, span.y); \ |
||
650 | for (i = 0; i < span.end; i++) { \ |
||
651 | const GLuint z = FixedToDepth(span.z); \ |
||
652 | if (z < zRow[i]) { \ |
||
653 | img[i] = pixel; \ |
||
654 | zRow[i] = z; \ |
||
655 | } \ |
||
656 | span.z += span.zStep; \ |
||
657 | } \ |
||
658 | } |
||
659 | #ifdef WIN32 |
||
660 | #include "..\swrast\s_tritemp.h" |
||
661 | #else |
||
662 | #include "swrast/s_tritemp.h" |
||
663 | #endif |
||
664 | |||
665 | |||
666 | |||
667 | /** |
||
668 | * Return pointer to an optimized triangle function if possible. |
||
669 | */ |
||
670 | static swrast_tri_func |
||
671 | osmesa_choose_triangle_function( struct gl_context *ctx ) |
||
672 | { |
||
673 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
674 | const SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
675 | |||
676 | if (osmesa->rb->DataType != GL_UNSIGNED_BYTE) |
||
677 | return (swrast_tri_func) NULL; |
||
678 | |||
679 | if (ctx->RenderMode != GL_RENDER) return (swrast_tri_func) NULL; |
||
680 | if (ctx->Polygon.SmoothFlag) return (swrast_tri_func) NULL; |
||
681 | if (ctx->Polygon.StippleFlag) return (swrast_tri_func) NULL; |
||
682 | if (ctx->Texture._EnabledUnits) return (swrast_tri_func) NULL; |
||
683 | if (osmesa->format != OSMESA_RGBA && |
||
684 | osmesa->format != OSMESA_BGRA && |
||
685 | osmesa->format != OSMESA_ARGB) return (swrast_tri_func) NULL; |
||
686 | if (ctx->Polygon.CullFlag && |
||
687 | ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) |
||
688 | return (swrast_tri_func) NULL; |
||
689 | |||
690 | if (swrast->_RasterMask == DEPTH_BIT && |
||
691 | ctx->Depth.Func == GL_LESS && |
||
692 | ctx->Depth.Mask == GL_TRUE && |
||
693 | ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { |
||
694 | if (ctx->Light.ShadeModel == GL_SMOOTH) { |
||
695 | return (swrast_tri_func) smooth_rgba_z_triangle; |
||
696 | } |
||
697 | else { |
||
698 | return (swrast_tri_func) flat_rgba_z_triangle; |
||
699 | } |
||
700 | } |
||
701 | return (swrast_tri_func) NULL; |
||
702 | } |
||
703 | |||
704 | |||
705 | |||
706 | /* Override for the swrast triangle-selection function. Try to use one |
||
707 | * of our internal triangle functions, otherwise fall back to the |
||
708 | * standard swrast functions. |
||
709 | */ |
||
710 | static void |
||
711 | osmesa_choose_triangle( struct gl_context *ctx ) |
||
712 | { |
||
713 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
714 | |||
715 | swrast->Triangle = osmesa_choose_triangle_function( ctx ); |
||
716 | if (!swrast->Triangle) |
||
717 | _swrast_choose_triangle( ctx ); |
||
718 | } |
||
719 | |||
720 | static void |
||
721 | osmesa_choose_line( struct gl_context *ctx ) |
||
722 | { |
||
723 | SWcontext *swrast = SWRAST_CONTEXT(ctx); |
||
724 | |||
725 | swrast->Line = osmesa_choose_line_function( ctx ); |
||
726 | if (!swrast->Line) |
||
727 | _swrast_choose_line( ctx ); |
||
728 | } |
||
729 | |||
730 | |||
731 | |||
732 | /** |
||
733 | * Recompute the values of the context's rowaddr array. |
||
734 | */ |
||
735 | static void |
||
736 | compute_row_addresses( OSMesaContext osmesa ) |
||
737 | { |
||
738 | GLint bytesPerPixel, bytesPerRow, i; |
||
739 | GLubyte *origin = (GLubyte *) osmesa->rb->Data; |
||
740 | GLint bpc; /* bytes per channel */ |
||
741 | GLint rowlength; /* in pixels */ |
||
742 | GLint height = osmesa->rb->Height; |
||
743 | |||
744 | if (osmesa->userRowLength) |
||
745 | rowlength = osmesa->userRowLength; |
||
746 | else |
||
747 | rowlength = osmesa->rb->Width; |
||
748 | |||
749 | if (osmesa->rb->DataType == GL_UNSIGNED_BYTE) |
||
750 | bpc = 1; |
||
751 | else if (osmesa->rb->DataType == GL_UNSIGNED_SHORT) |
||
752 | bpc = 2; |
||
753 | else if (osmesa->rb->DataType == GL_FLOAT) |
||
754 | bpc = 4; |
||
755 | else { |
||
756 | _mesa_problem(&osmesa->mesa, |
||
757 | "Unexpected datatype in osmesa::compute_row_addresses"); |
||
758 | return; |
||
759 | } |
||
760 | |||
761 | if ((osmesa->format == OSMESA_RGB) || (osmesa->format == OSMESA_BGR)) { |
||
762 | /* RGB mode */ |
||
763 | bytesPerPixel = 3 * bpc; |
||
764 | } |
||
765 | else if (osmesa->format == OSMESA_RGB_565) { |
||
766 | /* 5/6/5 RGB pixel in 16 bits */ |
||
767 | bytesPerPixel = 2; |
||
768 | } |
||
769 | else { |
||
770 | /* RGBA mode */ |
||
771 | bytesPerPixel = 4 * bpc; |
||
772 | } |
||
773 | |||
774 | bytesPerRow = rowlength * bytesPerPixel; |
||
775 | |||
776 | if (osmesa->yup) { |
||
777 | /* Y=0 is bottom line of window */ |
||
778 | for (i = 0; i < height; i++) { |
||
779 | osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + i * bytesPerRow); |
||
780 | } |
||
781 | } |
||
782 | else { |
||
783 | /* Y=0 is top line of window */ |
||
784 | for (i = 0; i < height; i++) { |
||
785 | GLint j = height - i - 1; |
||
786 | osmesa->rowaddr[i] = (GLvoid *) ((GLubyte *) origin + j * bytesPerRow); |
||
787 | } |
||
788 | } |
||
789 | } |
||
790 | |||
791 | |||
792 | |||
793 | /** |
||
794 | * Don't use _mesa_delete_renderbuffer since we can't free rb->Data. |
||
795 | */ |
||
796 | static void |
||
797 | osmesa_delete_renderbuffer(struct gl_renderbuffer *rb) |
||
798 | { |
||
799 | free(rb); |
||
800 | } |
||
801 | |||
802 | |||
803 | /** |
||
804 | * Allocate renderbuffer storage. We don't actually allocate any storage |
||
805 | * since we're using a user-provided buffer. |
||
806 | * Just set up all the gl_renderbuffer methods. |
||
807 | */ |
||
808 | static GLboolean |
||
809 | osmesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, |
||
810 | GLenum internalFormat, GLuint width, GLuint height) |
||
811 | { |
||
812 | const OSMesaContext osmesa = OSMESA_CONTEXT(ctx); |
||
813 | GLint bpc; /* bits per channel */ |
||
814 | |||
815 | if (rb->DataType == GL_UNSIGNED_BYTE) |
||
816 | bpc = 8; |
||
817 | else if (rb->DataType == GL_UNSIGNED_SHORT) |
||
818 | bpc = 16; |
||
819 | else |
||
820 | bpc = 32; |
||
821 | |||
822 | /* Note: we can ignoring internalFormat for "window-system" renderbuffers */ |
||
823 | (void) internalFormat; |
||
824 | |||
825 | if (osmesa->format == OSMESA_RGBA) { |
||
826 | if (rb->DataType == GL_UNSIGNED_BYTE) { |
||
827 | rb->GetRow = get_row_RGBA8; |
||
828 | rb->GetValues = get_values_RGBA8; |
||
829 | rb->PutRow = put_row_RGBA8; |
||
830 | rb->PutRowRGB = put_row_rgb_RGBA8; |
||
831 | rb->PutMonoRow = put_mono_row_RGBA8; |
||
832 | rb->PutValues = put_values_RGBA8; |
||
833 | rb->PutMonoValues = put_mono_values_RGBA8; |
||
834 | } |
||
835 | else if (rb->DataType == GL_UNSIGNED_SHORT) { |
||
836 | rb->GetRow = get_row_RGBA16; |
||
837 | rb->GetValues = get_values_RGBA16; |
||
838 | rb->PutRow = put_row_RGBA16; |
||
839 | rb->PutRowRGB = put_row_rgb_RGBA16; |
||
840 | rb->PutMonoRow = put_mono_row_RGBA16; |
||
841 | rb->PutValues = put_values_RGBA16; |
||
842 | rb->PutMonoValues = put_mono_values_RGBA16; |
||
843 | } |
||
844 | else { |
||
845 | rb->GetRow = get_row_RGBA32; |
||
846 | rb->GetValues = get_values_RGBA32; |
||
847 | rb->PutRow = put_row_RGBA32; |
||
848 | rb->PutRowRGB = put_row_rgb_RGBA32; |
||
849 | rb->PutMonoRow = put_mono_row_RGBA32; |
||
850 | rb->PutValues = put_values_RGBA32; |
||
851 | rb->PutMonoValues = put_mono_values_RGBA32; |
||
852 | } |
||
853 | } |
||
854 | else if (osmesa->format == OSMESA_BGRA) { |
||
855 | if (rb->DataType == GL_UNSIGNED_BYTE) { |
||
856 | rb->GetRow = get_row_BGRA8; |
||
857 | rb->GetValues = get_values_BGRA8; |
||
858 | rb->PutRow = put_row_BGRA8; |
||
859 | rb->PutRowRGB = put_row_rgb_BGRA8; |
||
860 | rb->PutMonoRow = put_mono_row_BGRA8; |
||
861 | rb->PutValues = put_values_BGRA8; |
||
862 | rb->PutMonoValues = put_mono_values_BGRA8; |
||
863 | } |
||
864 | else if (rb->DataType == GL_UNSIGNED_SHORT) { |
||
865 | rb->GetRow = get_row_BGRA16; |
||
866 | rb->GetValues = get_values_BGRA16; |
||
867 | rb->PutRow = put_row_BGRA16; |
||
868 | rb->PutRowRGB = put_row_rgb_BGRA16; |
||
869 | rb->PutMonoRow = put_mono_row_BGRA16; |
||
870 | rb->PutValues = put_values_BGRA16; |
||
871 | rb->PutMonoValues = put_mono_values_BGRA16; |
||
872 | } |
||
873 | else { |
||
874 | rb->GetRow = get_row_BGRA32; |
||
875 | rb->GetValues = get_values_BGRA32; |
||
876 | rb->PutRow = put_row_BGRA32; |
||
877 | rb->PutRowRGB = put_row_rgb_BGRA32; |
||
878 | rb->PutMonoRow = put_mono_row_BGRA32; |
||
879 | rb->PutValues = put_values_BGRA32; |
||
880 | rb->PutMonoValues = put_mono_values_BGRA32; |
||
881 | } |
||
882 | } |
||
883 | else if (osmesa->format == OSMESA_ARGB) { |
||
884 | if (rb->DataType == GL_UNSIGNED_BYTE) { |
||
885 | rb->GetRow = get_row_ARGB8; |
||
886 | rb->GetValues = get_values_ARGB8; |
||
887 | rb->PutRow = put_row_ARGB8; |
||
888 | rb->PutRowRGB = put_row_rgb_ARGB8; |
||
889 | rb->PutMonoRow = put_mono_row_ARGB8; |
||
890 | rb->PutValues = put_values_ARGB8; |
||
891 | rb->PutMonoValues = put_mono_values_ARGB8; |
||
892 | } |
||
893 | else if (rb->DataType == GL_UNSIGNED_SHORT) { |
||
894 | rb->GetRow = get_row_ARGB16; |
||
895 | rb->GetValues = get_values_ARGB16; |
||
896 | rb->PutRow = put_row_ARGB16; |
||
897 | rb->PutRowRGB = put_row_rgb_ARGB16; |
||
898 | rb->PutMonoRow = put_mono_row_ARGB16; |
||
899 | rb->PutValues = put_values_ARGB16; |
||
900 | rb->PutMonoValues = put_mono_values_ARGB16; |
||
901 | } |
||
902 | else { |
||
903 | rb->GetRow = get_row_ARGB32; |
||
904 | rb->GetValues = get_values_ARGB32; |
||
905 | rb->PutRow = put_row_ARGB32; |
||
906 | rb->PutRowRGB = put_row_rgb_ARGB32; |
||
907 | rb->PutMonoRow = put_mono_row_ARGB32; |
||
908 | rb->PutValues = put_values_ARGB32; |
||
909 | rb->PutMonoValues = put_mono_values_ARGB32; |
||
910 | } |
||
911 | } |
||
912 | else if (osmesa->format == OSMESA_RGB) { |
||
913 | if (rb->DataType == GL_UNSIGNED_BYTE) { |
||
914 | rb->GetRow = get_row_RGB8; |
||
915 | rb->GetValues = get_values_RGB8; |
||
916 | rb->PutRow = put_row_RGB8; |
||
917 | rb->PutRowRGB = put_row_rgb_RGB8; |
||
918 | rb->PutMonoRow = put_mono_row_RGB8; |
||
919 | rb->PutValues = put_values_RGB8; |
||
920 | rb->PutMonoValues = put_mono_values_RGB8; |
||
921 | } |
||
922 | else if (rb->DataType == GL_UNSIGNED_SHORT) { |
||
923 | rb->GetRow = get_row_RGB16; |
||
924 | rb->GetValues = get_values_RGB16; |
||
925 | rb->PutRow = put_row_RGB16; |
||
926 | rb->PutRowRGB = put_row_rgb_RGB16; |
||
927 | rb->PutMonoRow = put_mono_row_RGB16; |
||
928 | rb->PutValues = put_values_RGB16; |
||
929 | rb->PutMonoValues = put_mono_values_RGB16; |
||
930 | } |
||
931 | else { |
||
932 | rb->GetRow = get_row_RGB32; |
||
933 | rb->GetValues = get_values_RGB32; |
||
934 | rb->PutRow = put_row_RGB32; |
||
935 | rb->PutRowRGB = put_row_rgb_RGB32; |
||
936 | rb->PutMonoRow = put_mono_row_RGB32; |
||
937 | rb->PutValues = put_values_RGB32; |
||
938 | rb->PutMonoValues = put_mono_values_RGB32; |
||
939 | } |
||
940 | } |
||
941 | else if (osmesa->format == OSMESA_BGR) { |
||
942 | if (rb->DataType == GL_UNSIGNED_BYTE) { |
||
943 | rb->GetRow = get_row_BGR8; |
||
944 | rb->GetValues = get_values_BGR8; |
||
945 | rb->PutRow = put_row_BGR8; |
||
946 | rb->PutRowRGB = put_row_rgb_BGR8; |
||
947 | rb->PutMonoRow = put_mono_row_BGR8; |
||
948 | rb->PutValues = put_values_BGR8; |
||
949 | rb->PutMonoValues = put_mono_values_BGR8; |
||
950 | } |
||
951 | else if (rb->DataType == GL_UNSIGNED_SHORT) { |
||
952 | rb->GetRow = get_row_BGR16; |
||
953 | rb->GetValues = get_values_BGR16; |
||
954 | rb->PutRow = put_row_BGR16; |
||
955 | rb->PutRowRGB = put_row_rgb_BGR16; |
||
956 | rb->PutMonoRow = put_mono_row_BGR16; |
||
957 | rb->PutValues = put_values_BGR16; |
||
958 | rb->PutMonoValues = put_mono_values_BGR16; |
||
959 | } |
||
960 | else { |
||
961 | rb->GetRow = get_row_BGR32; |
||
962 | rb->GetValues = get_values_BGR32; |
||
963 | rb->PutRow = put_row_BGR32; |
||
964 | rb->PutRowRGB = put_row_rgb_BGR32; |
||
965 | rb->PutMonoRow = put_mono_row_BGR32; |
||
966 | rb->PutValues = put_values_BGR32; |
||
967 | rb->PutMonoValues = put_mono_values_BGR32; |
||
968 | } |
||
969 | } |
||
970 | else if (osmesa->format == OSMESA_RGB_565) { |
||
971 | ASSERT(rb->DataType == GL_UNSIGNED_BYTE); |
||
972 | rb->GetRow = get_row_RGB_565; |
||
973 | rb->GetValues = get_values_RGB_565; |
||
974 | rb->PutRow = put_row_RGB_565; |
||
975 | rb->PutRowRGB = put_row_rgb_RGB_565; |
||
976 | rb->PutMonoRow = put_mono_row_RGB_565; |
||
977 | rb->PutValues = put_values_RGB_565; |
||
978 | rb->PutMonoValues = put_mono_values_RGB_565; |
||
979 | } |
||
980 | else { |
||
981 | _mesa_problem(ctx, "bad pixel format in osmesa renderbuffer_storage"); |
||
982 | } |
||
983 | |||
984 | rb->Width = width; |
||
985 | rb->Height = height; |
||
986 | |||
987 | compute_row_addresses( osmesa ); |
||
988 | |||
989 | return GL_TRUE; |
||
990 | } |
||
991 | |||
992 | |||
993 | /** |
||
994 | * Allocate a new renderbuffer to describe the user-provided color buffer. |
||
995 | */ |
||
996 | static struct gl_renderbuffer * |
||
997 | new_osmesa_renderbuffer(struct gl_context *ctx, GLenum format, GLenum type) |
||
998 | { |
||
999 | const GLuint name = 0; |
||
1000 | struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name); |
||
1001 | if (rb) { |
||
1002 | rb->RefCount = 1; |
||
1003 | rb->Delete = osmesa_delete_renderbuffer; |
||
1004 | rb->AllocStorage = osmesa_renderbuffer_storage; |
||
1005 | |||
1006 | rb->InternalFormat = GL_RGBA; |
||
1007 | switch (type) { |
||
1008 | case GL_UNSIGNED_BYTE: |
||
1009 | rb->Format = MESA_FORMAT_RGBA8888; |
||
1010 | break; |
||
1011 | case GL_UNSIGNED_SHORT: |
||
1012 | rb->Format = MESA_FORMAT_RGBA_16; |
||
1013 | break; |
||
1014 | case GL_FLOAT: |
||
1015 | rb->Format = MESA_FORMAT_RGBA_FLOAT32; |
||
1016 | break; |
||
1017 | default: |
||
1018 | assert(0 && "Unexpected type in new_osmesa_renderbuffer()"); |
||
1019 | rb->Format = MESA_FORMAT_RGBA8888; |
||
1020 | } |
||
1021 | rb->_BaseFormat = GL_RGBA; |
||
1022 | rb->DataType = type; |
||
1023 | } |
||
1024 | return rb; |
||
1025 | } |
||
1026 | |||
1027 | |||
1028 | /**********************************************************************/ |
||
1029 | /***** Public Functions *****/ |
||
1030 | /**********************************************************************/ |
||
1031 | |||
1032 | |||
1033 | /** |
||
1034 | * Create an Off-Screen Mesa rendering context. The only attribute needed is |
||
1035 | * an RGBA vs Color-Index mode flag. |
||
1036 | * |
||
1037 | * Input: format - Must be GL_RGBA |
||
1038 | * sharelist - specifies another OSMesaContext with which to share |
||
1039 | * display lists. NULL indicates no sharing. |
||
1040 | * Return: an OSMesaContext or 0 if error |
||
1041 | */ |
||
1042 | GLAPI OSMesaContext GLAPIENTRY |
||
1043 | OSMesaCreateContext( GLenum format, OSMesaContext sharelist ) |
||
1044 | { |
||
1045 | return OSMesaCreateContextExt(format, DEFAULT_SOFTWARE_DEPTH_BITS, |
||
1046 | 8, 0, sharelist); |
||
1047 | } |
||
1048 | |||
1049 | |||
1050 | |||
1051 | /** |
||
1052 | * New in Mesa 3.5 |
||
1053 | * |
||
1054 | * Create context and specify size of ancillary buffers. |
||
1055 | */ |
||
1056 | GLAPI OSMesaContext GLAPIENTRY |
||
1057 | OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, |
||
1058 | GLint accumBits, OSMesaContext sharelist ) |
||
1059 | { |
||
1060 | OSMesaContext osmesa; |
||
1061 | struct dd_function_table functions; |
||
1062 | GLint rind, gind, bind, aind; |
||
1063 | GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0; |
||
1064 | |||
1065 | rind = gind = bind = aind = 0; |
||
1066 | if (format==OSMESA_RGBA) { |
||
1067 | redBits = CHAN_BITS; |
||
1068 | greenBits = CHAN_BITS; |
||
1069 | blueBits = CHAN_BITS; |
||
1070 | alphaBits = CHAN_BITS; |
||
1071 | rind = 0; |
||
1072 | gind = 1; |
||
1073 | bind = 2; |
||
1074 | aind = 3; |
||
1075 | } |
||
1076 | else if (format==OSMESA_BGRA) { |
||
1077 | redBits = CHAN_BITS; |
||
1078 | greenBits = CHAN_BITS; |
||
1079 | blueBits = CHAN_BITS; |
||
1080 | alphaBits = CHAN_BITS; |
||
1081 | bind = 0; |
||
1082 | gind = 1; |
||
1083 | rind = 2; |
||
1084 | aind = 3; |
||
1085 | } |
||
1086 | else if (format==OSMESA_ARGB) { |
||
1087 | redBits = CHAN_BITS; |
||
1088 | greenBits = CHAN_BITS; |
||
1089 | blueBits = CHAN_BITS; |
||
1090 | alphaBits = CHAN_BITS; |
||
1091 | aind = 0; |
||
1092 | rind = 1; |
||
1093 | gind = 2; |
||
1094 | bind = 3; |
||
1095 | } |
||
1096 | else if (format==OSMESA_RGB) { |
||
1097 | redBits = CHAN_BITS; |
||
1098 | greenBits = CHAN_BITS; |
||
1099 | blueBits = CHAN_BITS; |
||
1100 | alphaBits = 0; |
||
1101 | rind = 0; |
||
1102 | gind = 1; |
||
1103 | bind = 2; |
||
1104 | } |
||
1105 | else if (format==OSMESA_BGR) { |
||
1106 | redBits = CHAN_BITS; |
||
1107 | greenBits = CHAN_BITS; |
||
1108 | blueBits = CHAN_BITS; |
||
1109 | alphaBits = 0; |
||
1110 | rind = 2; |
||
1111 | gind = 1; |
||
1112 | bind = 0; |
||
1113 | } |
||
1114 | #if CHAN_TYPE == GL_UNSIGNED_BYTE |
||
1115 | else if (format==OSMESA_RGB_565) { |
||
1116 | redBits = 5; |
||
1117 | greenBits = 6; |
||
1118 | blueBits = 5; |
||
1119 | alphaBits = 0; |
||
1120 | rind = 0; /* not used */ |
||
1121 | gind = 0; |
||
1122 | bind = 0; |
||
1123 | } |
||
1124 | #endif |
||
1125 | else { |
||
1126 | return NULL; |
||
1127 | } |
||
1902 | serge | 1128 | |
1901 | serge | 1129 | osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context); |
1130 | if (osmesa) { |
||
1131 | osmesa->gl_visual = _mesa_create_visual( GL_FALSE, /* double buffer */ |
||
1132 | GL_FALSE, /* stereo */ |
||
1133 | redBits, |
||
1134 | greenBits, |
||
1135 | blueBits, |
||
1136 | alphaBits, |
||
1137 | depthBits, |
||
1138 | stencilBits, |
||
1139 | accumBits, |
||
1140 | accumBits, |
||
1141 | accumBits, |
||
1142 | alphaBits ? accumBits : 0, |
||
1143 | 1 /* num samples */ |
||
1144 | ); |
||
1145 | if (!osmesa->gl_visual) { |
||
1146 | free(osmesa); |
||
1147 | return NULL; |
||
1148 | } |
||
1149 | |||
1150 | /* Initialize device driver function table */ |
||
1151 | _mesa_init_driver_functions(&functions); |
||
1152 | /* override with our functions */ |
||
1153 | functions.GetString = get_string; |
||
1154 | functions.UpdateState = osmesa_update_state; |
||
1155 | functions.GetBufferSize = NULL; |
||
1902 | serge | 1156 | |
1901 | serge | 1157 | if (!_mesa_initialize_context(&osmesa->mesa, |
1158 | osmesa->gl_visual, |
||
1159 | sharelist ? &sharelist->mesa |
||
1160 | : (struct gl_context *) NULL, |
||
1161 | &functions, (void *) osmesa)) { |
||
1162 | _mesa_destroy_visual( osmesa->gl_visual ); |
||
1163 | free(osmesa); |
||
1164 | return NULL; |
||
1165 | } |
||
1902 | serge | 1166 | |
1901 | serge | 1167 | _mesa_enable_sw_extensions(&(osmesa->mesa)); |
1168 | _mesa_enable_1_3_extensions(&(osmesa->mesa)); |
||
1169 | _mesa_enable_1_4_extensions(&(osmesa->mesa)); |
||
1170 | _mesa_enable_1_5_extensions(&(osmesa->mesa)); |
||
1902 | serge | 1171 | _mesa_enable_2_0_extensions(&(osmesa->mesa)); |
1172 | _mesa_enable_2_1_extensions(&(osmesa->mesa)); |
||
1901 | serge | 1173 | |
1174 | osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual); |
||
1175 | if (!osmesa->gl_buffer) { |
||
1176 | _mesa_destroy_visual( osmesa->gl_visual ); |
||
1177 | _mesa_free_context_data( &osmesa->mesa ); |
||
1178 | free(osmesa); |
||
1179 | return NULL; |
||
1180 | } |
||
1181 | |||
1182 | /* Create depth/stencil/accum buffers. We'll create the color |
||
1183 | * buffer later in OSMesaMakeCurrent(). |
||
1184 | */ |
||
1185 | _mesa_add_soft_renderbuffers(osmesa->gl_buffer, |
||
1186 | GL_FALSE, /* color */ |
||
1187 | osmesa->gl_visual->haveDepthBuffer, |
||
1188 | osmesa->gl_visual->haveStencilBuffer, |
||
1189 | osmesa->gl_visual->haveAccumBuffer, |
||
1190 | GL_FALSE, /* alpha */ |
||
1191 | GL_FALSE /* aux */ ); |
||
1192 | |||
1193 | osmesa->format = format; |
||
1194 | osmesa->userRowLength = 0; |
||
1195 | osmesa->yup = GL_TRUE; |
||
1196 | osmesa->rInd = rind; |
||
1197 | osmesa->gInd = gind; |
||
1198 | osmesa->bInd = bind; |
||
1199 | osmesa->aInd = aind; |
||
1200 | |||
1201 | _mesa_meta_init(&osmesa->mesa); |
||
1202 | |||
1203 | /* Initialize the software rasterizer and helper modules. */ |
||
1204 | { |
||
1205 | struct gl_context *ctx = &osmesa->mesa; |
||
1206 | SWcontext *swrast; |
||
1207 | TNLcontext *tnl; |
||
1208 | |||
1209 | if (!_swrast_CreateContext( ctx ) || |
||
1210 | !_vbo_CreateContext( ctx ) || |
||
1211 | !_tnl_CreateContext( ctx ) || |
||
1212 | !_swsetup_CreateContext( ctx )) { |
||
1213 | _mesa_destroy_visual(osmesa->gl_visual); |
||
1214 | _mesa_free_context_data(ctx); |
||
1215 | free(osmesa); |
||
1216 | return NULL; |
||
1217 | } |
||
1218 | |||
1219 | _swsetup_Wakeup( ctx ); |
||
1220 | |||
1221 | /* use default TCL pipeline */ |
||
1222 | tnl = TNL_CONTEXT(ctx); |
||
1223 | tnl->Driver.RunPipeline = _tnl_run_pipeline; |
||
1224 | |||
1225 | /* Extend the software rasterizer with our optimized line and triangle |
||
1226 | * drawing functions. |
||
1227 | */ |
||
1228 | swrast = SWRAST_CONTEXT( ctx ); |
||
1229 | swrast->choose_line = osmesa_choose_line; |
||
1230 | swrast->choose_triangle = osmesa_choose_triangle; |
||
1231 | } |
||
1232 | } |
||
1233 | return osmesa; |
||
1234 | } |
||
1235 | |||
1236 | |||
1237 | /** |
||
1238 | * Destroy an Off-Screen Mesa rendering context. |
||
1239 | * |
||
1240 | * \param osmesa the context to destroy |
||
1241 | */ |
||
1242 | GLAPI void GLAPIENTRY |
||
1243 | OSMesaDestroyContext( OSMesaContext osmesa ) |
||
1244 | { |
||
1245 | if (osmesa) { |
||
1246 | if (osmesa->rb) |
||
1247 | _mesa_reference_renderbuffer(&osmesa->rb, NULL); |
||
1248 | |||
1249 | _mesa_meta_free( &osmesa->mesa ); |
||
1250 | |||
1251 | _swsetup_DestroyContext( &osmesa->mesa ); |
||
1252 | _tnl_DestroyContext( &osmesa->mesa ); |
||
1253 | _vbo_DestroyContext( &osmesa->mesa ); |
||
1254 | _swrast_DestroyContext( &osmesa->mesa ); |
||
1255 | |||
1256 | _mesa_destroy_visual( osmesa->gl_visual ); |
||
1257 | _mesa_reference_framebuffer( &osmesa->gl_buffer, NULL ); |
||
1258 | |||
1259 | _mesa_free_context_data( &osmesa->mesa ); |
||
1260 | free( osmesa ); |
||
1261 | } |
||
1262 | } |
||
1263 | |||
1264 | |||
1265 | /** |
||
1266 | * Bind an OSMesaContext to an image buffer. The image buffer is just a |
||
1267 | * block of memory which the client provides. Its size must be at least |
||
1268 | * as large as width*height*sizeof(type). Its address should be a multiple |
||
1269 | * of 4 if using RGBA mode. |
||
1270 | * |
||
1271 | * Image data is stored in the order of glDrawPixels: row-major order |
||
1272 | * with the lower-left image pixel stored in the first array position |
||
1273 | * (ie. bottom-to-top). |
||
1274 | * |
||
1275 | * If the context's viewport hasn't been initialized yet, it will now be |
||
1276 | * initialized to (0,0,width,height). |
||
1277 | * |
||
1278 | * Input: osmesa - the rendering context |
||
1279 | * buffer - the image buffer memory |
||
1280 | * type - data type for pixel components |
||
1281 | * Normally, only GL_UNSIGNED_BYTE and GL_UNSIGNED_SHORT_5_6_5 |
||
1282 | * are supported. But if Mesa's been compiled with CHAN_BITS==16 |
||
1283 | * then type may be GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE. And if |
||
1284 | * Mesa's been build with CHAN_BITS==32 then type may be GL_FLOAT, |
||
1285 | * GL_UNSIGNED_SHORT or GL_UNSIGNED_BYTE. |
||
1286 | * width, height - size of image buffer in pixels, at least 1 |
||
1287 | * Return: GL_TRUE if success, GL_FALSE if error because of invalid osmesa, |
||
1288 | * invalid buffer address, invalid type, width<1, height<1, |
||
1289 | * width>internal limit or height>internal limit. |
||
1290 | */ |
||
1291 | GLAPI GLboolean GLAPIENTRY |
||
1292 | OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type, |
||
1293 | GLsizei width, GLsizei height ) |
||
1294 | { |
||
1295 | if (!osmesa || !buffer || |
||
1296 | width < 1 || height < 1 || |
||
1297 | width > MAX_WIDTH || height > MAX_HEIGHT) { |
||
1298 | return GL_FALSE; |
||
1299 | } |
||
1300 | |||
1301 | if (osmesa->format == OSMESA_RGB_565 && type != GL_UNSIGNED_SHORT_5_6_5) { |
||
1302 | return GL_FALSE; |
||
1303 | } |
||
1304 | |||
1305 | #if 0 |
||
1306 | if (!(type == GL_UNSIGNED_BYTE || |
||
1307 | (type == GL_UNSIGNED_SHORT && CHAN_BITS >= 16) || |
||
1308 | (type == GL_FLOAT && CHAN_BITS == 32))) { |
||
1309 | /* i.e. is sizeof(type) * 8 > CHAN_BITS? */ |
||
1310 | return GL_FALSE; |
||
1311 | } |
||
1312 | #endif |
||
1313 | |||
1314 | osmesa_update_state( &osmesa->mesa, 0 ); |
||
1315 | |||
1316 | /* Call this periodically to detect when the user has begun using |
||
1317 | * GL rendering from multiple threads. |
||
1318 | */ |
||
1319 | _glapi_check_multithread(); |
||
1320 | |||
1321 | |||
1322 | /* Create a front/left color buffer which wraps the user-provided buffer. |
||
1323 | * There is no back color buffer. |
||
1324 | * If the user tries to use a 8, 16 or 32-bit/channel buffer that |
||
1325 | * doesn't match what Mesa was compiled for (CHAN_BITS) the |
||
1326 | * _mesa_add_renderbuffer() function will create a "wrapper" renderbuffer |
||
1327 | * that converts rendering from CHAN_BITS to the user-requested channel |
||
1328 | * size. |
||
1329 | */ |
||
1330 | if (!osmesa->rb) { |
||
1331 | osmesa->rb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type); |
||
1332 | _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT); |
||
1333 | _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb); |
||
1334 | assert(osmesa->rb->RefCount == 2); |
||
1335 | } |
||
1336 | |||
1337 | /* Set renderbuffer fields. Set width/height = 0 to force |
||
1338 | * osmesa_renderbuffer_storage() being called by _mesa_resize_framebuffer() |
||
1339 | */ |
||
1340 | osmesa->rb->Data = buffer; |
||
1341 | osmesa->rb->Width = osmesa->rb->Height = 0; |
||
1342 | |||
1343 | /* Set the framebuffer's size. This causes the |
||
1344 | * osmesa_renderbuffer_storage() function to get called. |
||
1345 | */ |
||
1346 | _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height); |
||
1347 | osmesa->gl_buffer->Initialized = GL_TRUE; /* XXX TEMPORARY? */ |
||
1348 | |||
1349 | _mesa_make_current( &osmesa->mesa, osmesa->gl_buffer, osmesa->gl_buffer ); |
||
1350 | |||
1351 | /* Remove renderbuffer attachment, then re-add. This installs the |
||
1352 | * renderbuffer adaptor/wrapper if needed (for bpp conversion). |
||
1353 | */ |
||
1354 | _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT); |
||
1355 | _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb); |
||
1356 | |||
1357 | |||
1358 | /* this updates the visual's red/green/blue/alphaBits fields */ |
||
1359 | _mesa_update_framebuffer_visual(osmesa->gl_buffer); |
||
1360 | |||
1361 | /* update the framebuffer size */ |
||
1362 | _mesa_resize_framebuffer(&osmesa->mesa, osmesa->gl_buffer, width, height); |
||
1363 | |||
1364 | return GL_TRUE; |
||
1365 | } |
||
1366 | |||
1367 | |||
1368 | |||
1369 | GLAPI OSMesaContext GLAPIENTRY |
||
1370 | OSMesaGetCurrentContext( void ) |
||
1371 | { |
||
1372 | struct gl_context *ctx = _mesa_get_current_context(); |
||
1373 | if (ctx) |
||
1374 | return (OSMesaContext) ctx; |
||
1375 | else |
||
1376 | return NULL; |
||
1377 | } |
||
1378 | |||
1379 | |||
1380 | |||
1381 | GLAPI void GLAPIENTRY |
||
1382 | OSMesaPixelStore( GLint pname, GLint value ) |
||
1383 | { |
||
1384 | OSMesaContext osmesa = OSMesaGetCurrentContext(); |
||
1385 | |||
1386 | switch (pname) { |
||
1387 | case OSMESA_ROW_LENGTH: |
||
1388 | if (value<0) { |
||
1389 | _mesa_error( &osmesa->mesa, GL_INVALID_VALUE, |
||
1390 | "OSMesaPixelStore(value)" ); |
||
1391 | return; |
||
1392 | } |
||
1393 | osmesa->userRowLength = value; |
||
1394 | break; |
||
1395 | case OSMESA_Y_UP: |
||
1396 | osmesa->yup = value ? GL_TRUE : GL_FALSE; |
||
1397 | break; |
||
1398 | default: |
||
1399 | _mesa_error( &osmesa->mesa, GL_INVALID_ENUM, "OSMesaPixelStore(pname)" ); |
||
1400 | return; |
||
1401 | } |
||
1402 | |||
1403 | compute_row_addresses( osmesa ); |
||
1404 | } |
||
1405 | |||
1406 | |||
1407 | GLAPI void GLAPIENTRY |
||
1408 | OSMesaGetIntegerv( GLint pname, GLint *value ) |
||
1409 | { |
||
1410 | OSMesaContext osmesa = OSMesaGetCurrentContext(); |
||
1411 | |||
1412 | switch (pname) { |
||
1413 | case OSMESA_WIDTH: |
||
1414 | if (osmesa->gl_buffer) |
||
1415 | *value = osmesa->gl_buffer->Width; |
||
1416 | else |
||
1417 | *value = 0; |
||
1418 | return; |
||
1419 | case OSMESA_HEIGHT: |
||
1420 | if (osmesa->gl_buffer) |
||
1421 | *value = osmesa->gl_buffer->Height; |
||
1422 | else |
||
1423 | *value = 0; |
||
1424 | return; |
||
1425 | case OSMESA_FORMAT: |
||
1426 | *value = osmesa->format; |
||
1427 | return; |
||
1428 | case OSMESA_TYPE: |
||
1429 | /* current color buffer's data type */ |
||
1430 | if (osmesa->rb) { |
||
1431 | *value = osmesa->rb->DataType; |
||
1432 | } |
||
1433 | else { |
||
1434 | *value = 0; |
||
1435 | } |
||
1436 | return; |
||
1437 | case OSMESA_ROW_LENGTH: |
||
1438 | *value = osmesa->userRowLength; |
||
1439 | return; |
||
1440 | case OSMESA_Y_UP: |
||
1441 | *value = osmesa->yup; |
||
1442 | return; |
||
1443 | case OSMESA_MAX_WIDTH: |
||
1444 | *value = MAX_WIDTH; |
||
1445 | return; |
||
1446 | case OSMESA_MAX_HEIGHT: |
||
1447 | *value = MAX_HEIGHT; |
||
1448 | return; |
||
1449 | default: |
||
1450 | _mesa_error(&osmesa->mesa, GL_INVALID_ENUM, "OSMesaGetIntergerv(pname)"); |
||
1451 | return; |
||
1452 | } |
||
1453 | } |
||
1454 | |||
1455 | |||
1456 | /** |
||
1457 | * Return the depth buffer associated with an OSMesa context. |
||
1458 | * Input: c - the OSMesa context |
||
1459 | * Output: width, height - size of buffer in pixels |
||
1460 | * bytesPerValue - bytes per depth value (2 or 4) |
||
1461 | * buffer - pointer to depth buffer values |
||
1462 | * Return: GL_TRUE or GL_FALSE to indicate success or failure. |
||
1463 | */ |
||
1464 | GLAPI GLboolean GLAPIENTRY |
||
1465 | OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height, |
||
1466 | GLint *bytesPerValue, void **buffer ) |
||
1467 | { |
||
1468 | struct gl_renderbuffer *rb = NULL; |
||
1469 | |||
1470 | if (c->gl_buffer) |
||
1471 | rb = c->gl_buffer->Attachment[BUFFER_DEPTH].Renderbuffer; |
||
1472 | |||
1473 | if (!rb || !rb->Data) { |
||
1474 | *width = 0; |
||
1475 | *height = 0; |
||
1476 | *bytesPerValue = 0; |
||
1477 | *buffer = 0; |
||
1478 | return GL_FALSE; |
||
1479 | } |
||
1480 | else { |
||
1481 | *width = rb->Width; |
||
1482 | *height = rb->Height; |
||
1483 | if (c->gl_visual->depthBits <= 16) |
||
1484 | *bytesPerValue = sizeof(GLushort); |
||
1485 | else |
||
1486 | *bytesPerValue = sizeof(GLuint); |
||
1487 | *buffer = rb->Data; |
||
1488 | return GL_TRUE; |
||
1489 | } |
||
1490 | } |
||
1491 | |||
1492 | |||
1493 | /** |
||
1494 | * Return the color buffer associated with an OSMesa context. |
||
1495 | * Input: c - the OSMesa context |
||
1496 | * Output: width, height - size of buffer in pixels |
||
1497 | * format - the pixel format (OSMESA_FORMAT) |
||
1498 | * buffer - pointer to color buffer values |
||
1499 | * Return: GL_TRUE or GL_FALSE to indicate success or failure. |
||
1500 | */ |
||
1501 | GLAPI GLboolean GLAPIENTRY |
||
1502 | OSMesaGetColorBuffer( OSMesaContext osmesa, GLint *width, |
||
1503 | GLint *height, GLint *format, void **buffer ) |
||
1504 | { |
||
1505 | if (osmesa->rb && osmesa->rb->Data) { |
||
1506 | *width = osmesa->rb->Width; |
||
1507 | *height = osmesa->rb->Height; |
||
1508 | *format = osmesa->format; |
||
1509 | *buffer = osmesa->rb->Data; |
||
1510 | return GL_TRUE; |
||
1511 | } |
||
1512 | else { |
||
1513 | *width = 0; |
||
1514 | *height = 0; |
||
1515 | *format = 0; |
||
1516 | *buffer = 0; |
||
1517 | return GL_FALSE; |
||
1518 | } |
||
1519 | } |
||
1520 | |||
1521 | |||
1522 | struct name_function |
||
1523 | { |
||
1524 | const char *Name; |
||
1525 | OSMESAproc Function; |
||
1526 | }; |
||
1527 | |||
1528 | static struct name_function functions[] = { |
||
1529 | { "OSMesaCreateContext", (OSMESAproc) OSMesaCreateContext }, |
||
1530 | { "OSMesaCreateContextExt", (OSMESAproc) OSMesaCreateContextExt }, |
||
1531 | { "OSMesaDestroyContext", (OSMESAproc) OSMesaDestroyContext }, |
||
1532 | { "OSMesaMakeCurrent", (OSMESAproc) OSMesaMakeCurrent }, |
||
1533 | { "OSMesaGetCurrentContext", (OSMESAproc) OSMesaGetCurrentContext }, |
||
1534 | { "OSMesaPixelsStore", (OSMESAproc) OSMesaPixelStore }, |
||
1535 | { "OSMesaGetIntegerv", (OSMESAproc) OSMesaGetIntegerv }, |
||
1536 | { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer }, |
||
1537 | { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer }, |
||
1538 | { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress }, |
||
1539 | { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp }, |
||
1540 | { NULL, NULL } |
||
1541 | }; |
||
1542 | |||
1543 | /* |
||
1544 | GLAPI OSMESAproc GLAPIENTRY |
||
1545 | OSMesaGetProcAddress( const char *funcName ) |
||
1546 | { |
||
1547 | int i; |
||
1548 | for (i = 0; functions[i].Name; i++) { |
||
1549 | if (strcmp(functions[i].Name, funcName) == 0) |
||
1550 | return functions[i].Function; |
||
1551 | } |
||
1552 | return _glapi_get_proc_address(funcName); |
||
1553 | } |
||
1554 | */ |
||
1555 | |||
1556 | GLAPI void GLAPIENTRY |
||
1557 | OSMesaColorClamp(GLboolean enable) |
||
1558 | { |
||
1559 | OSMesaContext osmesa = OSMesaGetCurrentContext(); |
||
1560 | |||
1561 | if (enable == GL_TRUE) { |
||
1562 | osmesa->mesa.Color.ClampFragmentColor = GL_TRUE; |
||
1563 | } |
||
1564 | else { |
||
1565 | osmesa->mesa.Color.ClampFragmentColor = GL_FIXED_ONLY_ARB; |
||
1566 | } |
||
1567 | }=>0)>>>1, |
||
1568 | |||
1569 |