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