Fix striding of color material inputs. (Fixes glean colorLitPerf)
[mesa.git] / src / mesa / drivers / allegro / amesa.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 3.0
4 * Copyright (C) 1995-1998 Brian Paul
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <allegro.h>
24 #include "context.h"
25 #include "matrix.h"
26 #include "mtypes.h"
27 #include "GL/amesa.h"
28
29
30 struct amesa_visual
31 {
32 GLvisual *GLVisual; /* inherit from GLvisual */
33 GLboolean DBFlag; /* double buffered? */
34 GLuint Depth; /* bits per pixel ( >= 15 ) */
35 };
36
37
38 struct amesa_buffer
39 {
40 GLframebuffer *GLBuffer; /* inherit from GLframebuffer */
41 GLuint Width, Height;
42 BITMAP *Screen;
43 BITMAP *Background;
44 BITMAP *Active;
45 };
46
47
48 struct amesa_context
49 {
50 GLcontext *GLContext; /* inherit from GLcontext */
51 AMesaVisual Visual;
52 AMesaBuffer Buffer;
53 GLuint ClearColor;
54 GLuint CurrentColor;
55 };
56
57
58 static void setup_dd_pointers(GLcontext *ctx);
59
60
61 /**********************************************************************/
62 /***** drawing functions *****/
63 /**********************************************************************/
64
65 #define FLIP(context, y) (context->Buffer->Height - (y) - 1)
66
67 #include "allegro/generic.h"
68 #include "allegro/direct.h"
69
70
71 /**********************************************************************/
72 /***** 15-bit accelerated drawing funcs *****/
73 /**********************************************************************/
74
75 IMPLEMENT_WRITE_RGBA_SPAN(15, unsigned short)
76 IMPLEMENT_WRITE_RGB_SPAN(15, unsigned short)
77 IMPLEMENT_WRITE_MONO_RGBA_SPAN(15, unsigned short)
78 IMPLEMENT_READ_RGBA_SPAN(15, unsigned short)
79 IMPLEMENT_WRITE_RGBA_PIXELS(15, unsigned short)
80 IMPLEMENT_WRITE_MONO_RGBA_PIXELS(15, unsigned short)
81 IMPLEMENT_READ_RGBA_PIXELS(15, unsigned short)
82
83
84 /**********************************************************************/
85 /***** 16-bit accelerated drawing funcs *****/
86 /**********************************************************************/
87
88 IMPLEMENT_WRITE_RGBA_SPAN(16, unsigned short)
89 IMPLEMENT_WRITE_RGB_SPAN(16, unsigned short)
90 IMPLEMENT_WRITE_MONO_RGBA_SPAN(16, unsigned short)
91 IMPLEMENT_READ_RGBA_SPAN(16, unsigned short)
92 IMPLEMENT_WRITE_RGBA_PIXELS(16, unsigned short)
93 IMPLEMENT_WRITE_MONO_RGBA_PIXELS(16, unsigned short)
94 IMPLEMENT_READ_RGBA_PIXELS(16, unsigned short)
95
96
97 /**********************************************************************/
98 /***** 32-bit accelerated drawing funcs *****/
99 /**********************************************************************/
100
101 IMPLEMENT_WRITE_RGBA_SPAN(32, unsigned long)
102 IMPLEMENT_WRITE_RGB_SPAN(32, unsigned long)
103 IMPLEMENT_WRITE_MONO_RGBA_SPAN(32, unsigned long)
104 IMPLEMENT_READ_RGBA_SPAN(32, unsigned long)
105 IMPLEMENT_WRITE_RGBA_PIXELS(32, unsigned long)
106 IMPLEMENT_WRITE_MONO_RGBA_PIXELS(32, unsigned long)
107 IMPLEMENT_READ_RGBA_PIXELS(32, unsigned long)
108
109
110 /**********************************************************************/
111 /***** Miscellaneous device driver funcs *****/
112 /**********************************************************************/
113
114 static GLboolean set_buffer(GLcontext *ctx, GLenum mode)
115 {
116 AMesaContext context = (AMesaContext)(ctx->DriverCtx);
117 GLboolean ok = GL_TRUE;
118
119 if (mode == GL_FRONT_LEFT)
120 context->Buffer->Active = context->Buffer->Screen;
121
122 else if (mode == GL_BACK_LEFT)
123 {
124 if (context->Buffer->Background)
125 context->Buffer->Active = context->Buffer->Background;
126 else
127 ok = GL_FALSE;
128 }
129
130 else
131 ok = GL_FALSE;
132
133 return ok;
134 }
135
136
137 static void get_buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
138 {
139 AMesaContext context = (AMesaContext)(ctx->DriverCtx);
140
141 *width = context->Buffer->Width;
142 *height = context->Buffer->Height;
143 }
144
145
146 /**********************************************************************/
147 /**********************************************************************/
148
149 static void setup_dd_pointers(GLcontext *ctx)
150 {
151 AMesaContext context = (AMesaContext)(ctx->DriverCtx);
152
153 /* Initialize all the pointers in the driver struct. Do this whenever */
154 /* a new context is made current or we change buffers via set_buffer! */
155
156 ctx->Driver.UpdateState = setup_dd_pointers;
157 ctx->Driver.SetBuffer = set_buffer;
158 ctx->Driver.GetBufferSize = get_buffer_size;
159
160 ctx->Driver.Color = set_color_generic;
161 ctx->Driver.ClearColor = clear_color_generic;
162 ctx->Driver.Clear = clear_generic;
163 ctx->Driver.WriteRGBASpan = write_rgba_span_generic;
164 ctx->Driver.WriteRGBSpan = write_rgb_span_generic;
165 ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span_generic;
166 ctx->Driver.WriteRGBAPixels = write_rgba_pixels_generic;
167 ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_generic;
168 ctx->Driver.ReadRGBASpan = read_rgba_span_generic;
169 ctx->Driver.ReadRGBAPixels = read_rgba_pixels_generic;
170
171 if (context->Buffer->Active != screen)
172 {
173 switch (context->Visual->Depth)
174 {
175 case 15:
176 ctx->Driver.WriteRGBASpan = write_rgba_span_15;
177 ctx->Driver.WriteRGBSpan = write_rgb_span_15;
178 ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span_15;
179 ctx->Driver.WriteRGBAPixels = write_rgba_pixels_15;
180 ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_15;
181 ctx->Driver.ReadRGBASpan = read_rgba_span_15;
182 ctx->Driver.ReadRGBAPixels = read_rgba_pixels_15;
183 break;
184
185 case 16:
186 ctx->Driver.WriteRGBASpan = write_rgba_span_16;
187 ctx->Driver.WriteRGBSpan = write_rgb_span_16;
188 ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span_16;
189 ctx->Driver.WriteRGBAPixels = write_rgba_pixels_16;
190 ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_16;
191 ctx->Driver.ReadRGBASpan = read_rgba_span_16;
192 ctx->Driver.ReadRGBAPixels = read_rgba_pixels_16;
193 break;
194
195 case 32:
196 ctx->Driver.WriteRGBASpan = write_rgba_span_32;
197 ctx->Driver.WriteRGBSpan = write_rgb_span_32;
198 ctx->Driver.WriteMonoRGBASpan = write_mono_rgba_span_32;
199 ctx->Driver.WriteRGBAPixels = write_rgba_pixels_32;
200 ctx->Driver.WriteMonoRGBAPixels = write_mono_rgba_pixels_32;
201 ctx->Driver.ReadRGBASpan = read_rgba_span_32;
202 ctx->Driver.ReadRGBAPixels = read_rgba_pixels_32;
203 break;
204 }
205 }
206 }
207
208
209 /**********************************************************************/
210 /***** AMesa Public API Functions *****/
211 /**********************************************************************/
212
213
214 AMesaVisual AMesaCreateVisual(GLboolean dbFlag, GLint depth,
215 GLint depthSize, GLint stencilSize, GLint accumSize)
216 {
217 AMesaVisual visual;
218 GLbyte redBits, greenBits, blueBits;
219
220 visual = (AMesaVisual)calloc(1, sizeof(struct amesa_visual));
221 if (!visual)
222 return NULL;
223
224 switch (depth)
225 {
226 case 15:
227 redBits = 5;
228 greenBits = 5;
229 blueBits = 5;
230 break;
231
232 case 16:
233 redBits = 5;
234 greenBits = 6;
235 blueBits = 5;
236 break;
237
238 case 24: case 32:
239 redBits = 8;
240 greenBits = 8;
241 blueBits = 8;
242 break;
243
244 default:
245 free(visual);
246 return NULL;
247 }
248
249 visual->DBFlag = dbFlag;
250 visual->Depth = depth;
251 visual->GLVisual = _mesa_create_visual(GL_TRUE, /* rgb mode */
252 dbFlag, /* db_flag */
253 GL_FALSE, /* stereo */
254 redBits, greenBits, blueBits, 8,
255 0, /* index bits */
256 depthSize, /* depth bits */
257 stencilSize,/* stencil bits */
258 accumSize, /* accum bits */
259 accumSize, /* accum bits */
260 accumSize, /* accum bits */
261 accumSize, /* accum bits */
262 1 );
263 if (!visual->GLVisual)
264 {
265 free(visual);
266 return NULL;
267 }
268
269 return visual;
270 }
271
272
273 void AMesaDestroyVisual(AMesaVisual visual)
274 {
275 _mesa_destroy_visual(visual->GLVisual);
276 free(visual);
277 }
278
279
280 AMesaBuffer AMesaCreateBuffer(AMesaVisual visual,
281 GLint width, GLint height)
282 {
283 AMesaBuffer buffer;
284
285 buffer = (AMesaBuffer)calloc(1, sizeof(struct amesa_buffer));
286 if (!buffer)
287 return NULL;
288
289 buffer->Screen = NULL;
290 buffer->Background = NULL;
291 buffer->Active = NULL;
292 buffer->Width = width;
293 buffer->Height = height;
294
295 if (visual->DBFlag)
296 {
297 buffer->Background = create_bitmap_ex(visual->Depth, width, height);
298 if (!buffer->Background)
299 {
300 free(buffer);
301 return NULL;
302 }
303 }
304
305 buffer->GLBuffer = _mesa_create_framebuffer(visual->GLVisual);
306 if (!buffer->GLBuffer)
307 {
308 if (buffer->Background) destroy_bitmap(buffer->Background);
309 free(buffer);
310 return NULL;
311 }
312
313 return buffer;
314 }
315
316
317 void AMesaDestroyBuffer(AMesaBuffer buffer)
318 {
319 if (buffer->Screen) destroy_bitmap(buffer->Screen);
320 if (buffer->Background) destroy_bitmap(buffer->Background);
321 _mesa_destroy_framebuffer(buffer->GLBuffer);
322 free(buffer);
323 }
324
325
326 AMesaContext AMesaCreateContext(AMesaVisual visual,
327 AMesaContext share)
328 {
329 AMesaContext context;
330 GLboolean direct = GL_FALSE;
331
332 context = (AMesaContext)calloc(1, sizeof(struct amesa_context));
333 if (!context)
334 return NULL;
335
336 context->Visual = visual;
337 context->Buffer = NULL;
338 context->ClearColor = 0;
339 context->CurrentColor = 0;
340 context->GLContext = _mesa_create_context(visual->GLVisual,
341 share ? share->GLContext : NULL,
342 (void*)context,
343 direct);
344 if (!context->GLContext)
345 {
346 free(context);
347 return NULL;
348 }
349
350 return context;
351 }
352
353
354 void AMesaDestroyContext(AMesaContext context)
355 {
356 _mesa_destroy_context(context->GLContext);
357 free(context);
358 }
359
360
361 GLboolean AMesaMakeCurrent(AMesaContext context, AMesaBuffer buffer)
362 {
363 if (context && buffer) {
364 set_color_depth(context->Visual->Depth);
365 if (set_gfx_mode(GFX_AUTODETECT, buffer->Width, buffer->Height, 0, 0) != 0)
366 return GL_FALSE;
367
368 context->Buffer = buffer;
369 buffer->Screen = screen;
370 buffer->Active = buffer->Background ? buffer->Background : screen;
371
372 setup_dd_pointers(context->GLContext);
373 _mesa_make_current(context->GLContext, buffer->GLBuffer);
374 _mesa_set_viewport(context->GLContext, 0, 0, buffer->Width, buffer->Height);
375 }
376 else {
377 destroy_bitmap(context->Buffer->Screen);
378 context->Buffer->Screen = NULL;
379 context->Buffer->Active = NULL;
380 context->Buffer = NULL;
381 _mesa_make_current(NULL, NULL);
382 }
383
384 return GL_TRUE;
385 }
386
387
388 void AMesaSwapBuffers(AMesaBuffer buffer)
389 {
390 if (buffer->Background) {
391 blit(buffer->Background, buffer->Screen,
392 0, 0, 0, 0,
393 buffer->Width, buffer->Height);
394 }
395 }