Subversion Repositories Kolibri OS

Rev

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
}
1568
 
1569