fix tabbing
[mesa.git] / src / mesa / drivers / directfb / idirectfbgl_mesa.c
1 /*
2 * Copyright (C) 2004-2007 Claudio Ciccani <klan@directfb.org>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 *
19 * Based on glfbdev.c, written by Brian Paul.
20 *
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26
27 #include <pthread.h>
28
29 #include <directfb.h>
30 #include <directfb_version.h>
31
32 #include <directfbgl.h>
33
34 #include <direct/mem.h>
35 #include <direct/messages.h>
36 #include <direct/interface.h>
37
38 #undef CLAMP
39 #include "glheader.h"
40 #include "buffers.h"
41 #include "context.h"
42 #include "extensions.h"
43 #include "framebuffer.h"
44 #include "renderbuffer.h"
45 #include "imports.h"
46 #include "texformat.h"
47 #include "teximage.h"
48 #include "texstore.h"
49 #include "vbo/vbo.h"
50 #include "swrast/swrast.h"
51 #include "swrast_setup/swrast_setup.h"
52 #include "tnl/tnl.h"
53 #include "tnl/t_context.h"
54 #include "tnl/t_pipeline.h"
55 #include "drivers/common/driverfuncs.h"
56
57
58 #define VERSION_CODE( M, m, r ) (((M) * 1000) + ((m) * 100) + ((r)))
59 #define DIRECTFB_VERSION_CODE VERSION_CODE( DIRECTFB_MAJOR_VERSION, \
60 DIRECTFB_MINOR_VERSION, \
61 DIRECTFB_MICRO_VERSION )
62
63
64 static DFBResult
65 Probe( void *data );
66
67 static DFBResult
68 Construct( IDirectFBGL *thiz,
69 IDirectFBSurface *surface );
70
71 #include <direct/interface_implementation.h>
72
73 DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBGL, Mesa )
74
75 /*
76 * private data struct of IDirectFBGL
77 */
78 typedef struct {
79 int ref; /* reference counter */
80
81 int locked;
82
83 IDirectFBSurface *surface;
84 DFBSurfacePixelFormat format;
85 int width;
86 int height;
87
88 struct {
89 GLubyte *start;
90 GLubyte *end;
91 int pitch;
92 } video;
93
94 GLvisual visual;
95 GLframebuffer framebuffer;
96 GLcontext context;
97 struct gl_renderbuffer render;
98 } IDirectFBGL_data;
99
100 /******************************************************************************/
101
102 static pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER;
103 static unsigned int global_ref = 0;
104
105 static inline int directfbgl_init( void )
106 {
107 pthread_mutexattr_t attr;
108 int ret;
109
110 if (global_ref++)
111 return 0;
112
113 pthread_mutexattr_init( &attr );
114 pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK );
115 ret = pthread_mutex_init( &global_lock, &attr );
116 pthread_mutexattr_destroy( &attr );
117
118 return ret;
119 }
120
121 static inline void directfbgl_finish( void )
122 {
123 if (--global_ref == 0)
124 pthread_mutex_destroy( &global_lock );
125 }
126
127 #define directfbgl_lock() pthread_mutex_lock( &global_lock )
128 #define directfbgl_unlock() pthread_mutex_unlock( &global_lock )
129
130 /******************************************************************************/
131
132 static bool directfbgl_init_visual ( GLvisual *visual,
133 DFBSurfacePixelFormat format );
134 static bool directfbgl_create_context ( GLcontext *context,
135 GLframebuffer *framebuffer,
136 GLvisual *visual,
137 DFBSurfacePixelFormat format,
138 IDirectFBGL_data *data );
139 static void directfbgl_destroy_context( GLcontext *context,
140 GLframebuffer *framebuffer );
141
142 /******************************************************************************/
143
144
145 static void
146 IDirectFBGL_Mesa_Destruct( IDirectFBGL *thiz )
147 {
148 IDirectFBGL_data *data = (IDirectFBGL_data*) thiz->priv;
149
150 directfbgl_destroy_context( &data->context, &data->framebuffer );
151
152 if (data->surface)
153 data->surface->Release( data->surface );
154
155 DIRECT_DEALLOCATE_INTERFACE( thiz );
156
157 directfbgl_finish();
158 }
159
160 static DFBResult
161 IDirectFBGL_Mesa_AddRef( IDirectFBGL *thiz )
162 {
163 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
164
165 data->ref++;
166
167 return DFB_OK;
168 }
169
170 static DFBResult
171 IDirectFBGL_Mesa_Release( IDirectFBGL *thiz )
172 {
173 DIRECT_INTERFACE_GET_DATA( IDirectFBGL )
174
175 if (--data->ref == 0)
176 IDirectFBGL_Mesa_Destruct( thiz );
177
178 return DFB_OK;
179 }
180
181 static DFBResult
182 IDirectFBGL_Mesa_Lock( IDirectFBGL *thiz )
183 {
184 IDirectFBSurface *surface;
185 int width = 0;
186 int height = 0;
187 DFBResult ret;
188
189 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
190
191 if (data->locked) {
192 data->locked++;
193 return DFB_OK;
194 }
195
196 if (directfbgl_lock())
197 return DFB_LOCKED;
198
199 surface = data->surface;
200 surface->GetSize( surface, &width, &height );
201
202 ret = surface->Lock( surface, DSLF_READ | DSLF_WRITE,
203 (void*)&data->video.start, &data->video.pitch );
204 if (ret) {
205 D_ERROR( "DirectFBGL/Mesa: couldn't lock surface.\n" );
206 directfbgl_unlock();
207 return ret;
208 }
209 data->video.end = data->video.start + (height-1) * data->video.pitch;
210
211 data->render.Data = data->video.start;
212
213 _mesa_make_current( &data->context,
214 &data->framebuffer, &data->framebuffer );
215
216 if (data->width != width || data->height != height) {
217 _mesa_resize_framebuffer( &data->context,
218 &data->framebuffer, width, height );
219 data->width = width;
220 data->height = height;
221 }
222
223 data->locked++;
224
225 return DFB_OK;
226 }
227
228 static DFBResult
229 IDirectFBGL_Mesa_Unlock( IDirectFBGL *thiz )
230 {
231 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
232
233 if (!data->locked)
234 return DFB_OK;
235
236 if (--data->locked == 0) {
237 _mesa_make_current( NULL, NULL, NULL );
238
239 data->surface->Unlock( data->surface );
240
241 directfbgl_unlock();
242 }
243
244 return DFB_OK;
245 }
246
247 static DFBResult
248 IDirectFBGL_Mesa_GetAttributes( IDirectFBGL *thiz,
249 DFBGLAttributes *attributes )
250 {
251 DFBSurfaceCapabilities caps;
252 GLvisual *visual;
253
254 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
255
256 if (!attributes)
257 return DFB_INVARG;
258
259 data->surface->GetCapabilities( data->surface, &caps );
260
261 visual = &data->visual;
262
263 attributes->buffer_size = visual->rgbBits ? : visual->indexBits;
264 attributes->depth_size = visual->depthBits;
265 attributes->stencil_size = visual->stencilBits;
266 attributes->aux_buffers = visual->numAuxBuffers;
267 attributes->red_size = visual->redBits;
268 attributes->green_size = visual->greenBits;
269 attributes->blue_size = visual->blueBits;
270 attributes->alpha_size = visual->alphaBits;
271 attributes->accum_red_size = visual->accumRedBits;
272 attributes->accum_green_size = visual->accumGreenBits;
273 attributes->accum_blue_size = visual->accumBlueBits;
274 attributes->accum_alpha_size = visual->accumAlphaBits;
275 attributes->double_buffer = ((caps & DSCAPS_FLIPPING) != 0);
276 attributes->stereo = (visual->stereoMode != 0);
277
278 return DFB_OK;
279 }
280
281 #if DIRECTFBGL_INTERFACE_VERSION >= 1
282 static DFBResult
283 IDirectFBGL_Mesa_GetProcAddress( IDirectFBGL *thiz,
284 const char *name,
285 void **ret_address )
286 {
287 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
288
289 if (!name)
290 return DFB_INVARG;
291
292 if (!ret_address)
293 return DFB_INVARG;
294
295 *ret_address = _glapi_get_proc_address( name );
296
297 return (*ret_address) ? DFB_OK : DFB_UNSUPPORTED;
298 }
299 #endif
300
301
302 /* exported symbols */
303
304 static DFBResult
305 Probe( void *data )
306 {
307 return DFB_OK;
308 }
309
310 static DFBResult
311 Construct( IDirectFBGL *thiz, IDirectFBSurface *surface )
312 {
313 DFBResult ret;
314
315 /* Initialize global resources. */
316 if (directfbgl_init())
317 return DFB_INIT;
318
319 /* Allocate interface data. */
320 DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IDirectFBGL );
321
322 /* Initialize interface data. */
323 data->ref = 1;
324
325 /* Duplicate destination surface. */
326 ret = surface->GetSubSurface( surface, NULL, &data->surface );
327 if (ret) {
328 IDirectFBGL_Mesa_Destruct( thiz );
329 return ret;
330 }
331
332 data->surface->GetPixelFormat( data->surface, &data->format );
333 data->surface->GetSize( data->surface, &data->width, &data->height );
334
335 /* Configure visual. */
336 if (!directfbgl_init_visual( &data->visual, data->format )) {
337 D_ERROR( "DirectFBGL/Mesa: failed to initialize visual.\n" );
338 IDirectFBGL_Mesa_Destruct( thiz );
339 return DFB_UNSUPPORTED;
340 }
341
342 /* Create context. */
343 if (!directfbgl_create_context( &data->context, &data->framebuffer,
344 &data->visual, data->format, data )) {
345 D_ERROR( "DirectFBGL/Mesa: failed to create context.\n" );
346 IDirectFBGL_Mesa_Destruct( thiz );
347 return DFB_UNSUPPORTED;
348 }
349
350 /* Assign interface pointers. */
351 thiz->AddRef = IDirectFBGL_Mesa_AddRef;
352 thiz->Release = IDirectFBGL_Mesa_Release;
353 thiz->Lock = IDirectFBGL_Mesa_Lock;
354 thiz->Unlock = IDirectFBGL_Mesa_Unlock;
355 thiz->GetAttributes = IDirectFBGL_Mesa_GetAttributes;
356 #if DIRECTFBGL_INTERFACE_VERSION >= 1
357 thiz->GetProcAddress = IDirectFBGL_Mesa_GetProcAddress;
358 #endif
359
360 return DFB_OK;
361 }
362
363
364 /***************************** Driver functions ******************************/
365
366 static const GLubyte*
367 dfbGetString( GLcontext *ctx, GLenum pname )
368 {
369 return NULL;
370 }
371
372 static void
373 dfbUpdateState( GLcontext *ctx, GLuint new_state )
374 {
375 _swrast_InvalidateState( ctx, new_state );
376 _swsetup_InvalidateState( ctx, new_state );
377 _vbo_InvalidateState( ctx, new_state );
378 _tnl_InvalidateState( ctx, new_state );
379 }
380
381 static void
382 dfbGetBufferSize( GLframebuffer *buffer, GLuint *width, GLuint *height )
383 {
384 GLcontext *ctx = _mesa_get_current_context();
385 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
386
387 *width = (GLuint) data->width;
388 *height = (GLuint) data->height;
389 }
390
391 /**
392 * We only implement this function as a mechanism to check if the
393 * framebuffer size has changed (and update corresponding state).
394 */
395 static void
396 dfbSetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
397 {
398 /* Nothing to do (the surface can't be resized while it's locked). */
399 return;
400 }
401
402 static void
403 dfbClear( GLcontext *ctx, GLbitfield mask )
404 {
405 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
406
407 #define BUFFER_BIT_MASK (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT | \
408 BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT )
409 if (mask & BUFFER_BIT_MASK &&
410 ctx->Color.ColorMask[0] &&
411 ctx->Color.ColorMask[1] &&
412 ctx->Color.ColorMask[2] &&
413 ctx->Color.ColorMask[3])
414 {
415 DFBRegion clip;
416 GLubyte a, r, g, b;
417
418 UNCLAMPED_FLOAT_TO_UBYTE( a, ctx->Color.ClearColor[ACOMP] );
419 UNCLAMPED_FLOAT_TO_UBYTE( r, ctx->Color.ClearColor[RCOMP] );
420 UNCLAMPED_FLOAT_TO_UBYTE( g, ctx->Color.ClearColor[GCOMP] );
421 UNCLAMPED_FLOAT_TO_UBYTE( b, ctx->Color.ClearColor[BCOMP] );
422
423 clip.x1 = ctx->DrawBuffer->_Xmin;
424 clip.y1 = ctx->DrawBuffer->_Ymin;
425 clip.x2 = ctx->DrawBuffer->_Xmax - 1;
426 clip.y2 = ctx->DrawBuffer->_Ymax - 1;
427 data->surface->SetClip( data->surface, &clip );
428
429 data->surface->Unlock( data->surface );
430
431 data->surface->Clear( data->surface, r, g, b, a );
432
433 data->surface->Lock( data->surface, DSLF_READ | DSLF_WRITE,
434 (void*)&data->video.start, &data->video.pitch );
435 data->video.end = data->video.start + (data->height-1) * data->video.pitch;
436 data->render.Data = data->video.start;
437
438 mask &= ~BUFFER_BIT_MASK;
439 }
440 #undef BUFFER_BIT_MASK
441
442 if (mask)
443 _swrast_Clear( ctx, mask );
444 }
445
446
447 /************************ RenderBuffer functions *****************************/
448
449 static void
450 dfbDeleteRenderbuffer( struct gl_renderbuffer *render )
451 {
452 return;
453 }
454
455 static GLboolean
456 dfbRenderbufferStorage( GLcontext *ctx, struct gl_renderbuffer *render,
457 GLenum internalFormat, GLuint width, GLuint height )
458 {
459 return GL_TRUE;
460 }
461
462
463 /***************************** Span functions ********************************/
464
465 /* RGB332 */
466 #define NAME(PREFIX) PREFIX##_RGB332
467 #define FORMAT GL_RGBA8
468 #define RB_TYPE GLubyte
469 #define SPAN_VARS \
470 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
471 #define INIT_PIXEL_PTR(P, X, Y) \
472 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X);
473 #define INC_PIXEL_PTR(P) P += 1
474 #define STORE_PIXEL(P, X, Y, S) \
475 *P = ( (((S[RCOMP]) & 0xe0) ) | \
476 (((S[GCOMP]) & 0xe0) >> 3) | \
477 (((S[BCOMP]) ) >> 6) )
478 #define FETCH_PIXEL(D, P) \
479 D[RCOMP] = ((*P & 0xe0) ); \
480 D[GCOMP] = ((*P & 0x1c) << 3); \
481 D[BCOMP] = ((*P & 0x03) << 6); \
482 D[ACOMP] = 0xff
483
484 #include "swrast/s_spantemp.h"
485
486 /* ARGB4444 */
487 #define NAME(PREFIX) PREFIX##_ARGB4444
488 #define FORMAT GL_RGBA8
489 #define RB_TYPE GLubyte
490 #define SPAN_VARS \
491 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
492 #define INIT_PIXEL_PTR(P, X, Y) \
493 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
494 #define INC_PIXEL_PTR(P) P += 1
495 #define STORE_PIXEL_RGB(P, X, Y, S) \
496 *P = ( 0xf000 | \
497 (((S[RCOMP]) & 0xf0) << 4) | \
498 (((S[GCOMP]) & 0xf0) ) | \
499 (((S[BCOMP]) & 0xf0) >> 4) )
500 #define STORE_PIXEL(P, X, Y, S) \
501 *P = ( (((S[ACOMP]) & 0xf0) << 8) | \
502 (((S[RCOMP]) & 0xf0) << 4) | \
503 (((S[GCOMP]) & 0xf0) ) | \
504 (((S[BCOMP]) & 0xf0) >> 4) )
505 #define FETCH_PIXEL(D, P) \
506 D[RCOMP] = ((*P & 0x0f00) >> 4); \
507 D[GCOMP] = ((*P & 0x00f0) ); \
508 D[BCOMP] = ((*P & 0x000f) << 4); \
509 D[ACOMP] = ((*P & 0xf000) >> 8)
510
511 #include "swrast/s_spantemp.h"
512
513 /* ARGB2554 */
514 #define NAME(PREFIX) PREFIX##_ARGB2554
515 #define FORMAT GL_RGBA8
516 #define RB_TYPE GLubyte
517 #define SPAN_VARS \
518 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
519 #define INIT_PIXEL_PTR(P, X, Y) \
520 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
521 #define INC_PIXEL_PTR(P) P += 1
522 #define STORE_PIXEL_RGB(P, X, Y, S) \
523 *P = ( 0xc000 | \
524 (((S[RCOMP]) & 0xf8) << 6) | \
525 (((S[GCOMP]) & 0xf8) << 1) | \
526 (((S[BCOMP]) & 0xf0) >> 4) )
527 #define STORE_PIXEL(P, X, Y, S) \
528 *P = ( (((S[ACOMP]) & 0xc0) << 8) | \
529 (((S[RCOMP]) & 0xf8) << 6) | \
530 (((S[GCOMP]) & 0xf8) << 1) | \
531 (((S[BCOMP]) & 0xf0) >> 4) )
532 #define FETCH_PIXEL(D, P) \
533 D[RCOMP] = ((*P & 0x3e00) >> 9); \
534 D[GCOMP] = ((*P & 0x01f0) >> 4); \
535 D[BCOMP] = ((*P & 0x000f) << 4); \
536 D[ACOMP] = ((*P & 0xc000) >> 14)
537
538 #include "swrast/s_spantemp.h"
539
540 /* ARGB1555 */
541 #define NAME(PREFIX) PREFIX##_ARGB1555
542 #define FORMAT GL_RGBA8
543 #define RB_TYPE GLubyte
544 #define SPAN_VARS \
545 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
546 #define INIT_PIXEL_PTR(P, X, Y) \
547 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
548 #define INC_PIXEL_PTR(P) P += 1
549 #define STORE_PIXEL_RGB(P, X, Y, S) \
550 *P = ( 0x8000 | \
551 (((S[RCOMP]) & 0xf8) << 7) | \
552 (((S[GCOMP]) & 0xf8) << 2) | \
553 (((S[BCOMP]) ) >> 3) )
554 #define STORE_PIXEL(P, X, Y, S) \
555 *P = ( (((S[ACOMP]) & 0x80) << 16) | \
556 (((S[RCOMP]) & 0xf8) << 7) | \
557 (((S[GCOMP]) & 0xf8) << 2) | \
558 (((S[BCOMP]) ) >> 3) )
559 #define FETCH_PIXEL(D, P) \
560 D[RCOMP] = ((*P & 0x7c00) >> 7); \
561 D[GCOMP] = ((*P & 0x03e0) >> 2); \
562 D[BCOMP] = ((*P & 0x001f) << 3); \
563 D[ACOMP] = ((*P & 0x8000) ? 0xff : 0)
564
565 #include "swrast/s_spantemp.h"
566
567 /* RGB16 */
568 #define NAME(PREFIX) PREFIX##_RGB16
569 #define FORMAT GL_RGBA8
570 #define RB_TYPE GLubyte
571 #define SPAN_VARS \
572 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
573 #define INIT_PIXEL_PTR(P, X, Y) \
574 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
575 #define INC_PIXEL_PTR(P) P += 1
576 #define STORE_PIXEL(P, X, Y, S) \
577 *P = ( (((S[RCOMP]) & 0xf8) << 8) | \
578 (((S[GCOMP]) & 0xfc) << 3) | \
579 (((S[BCOMP]) ) >> 3) )
580 #define FETCH_PIXEL(D, P) \
581 D[RCOMP] = ((*P & 0xf800) >> 8); \
582 D[GCOMP] = ((*P & 0x07e0) >> 3); \
583 D[BCOMP] = ((*P & 0x001f) << 3); \
584 D[ACOMP] = 0xff
585
586 #include "swrast/s_spantemp.h"
587
588 /* RGB24 */
589 #define NAME(PREFIX) PREFIX##_RGB24
590 #define FORMAT GL_RGBA8
591 #define RB_TYPE GLubyte
592 #define SPAN_VARS \
593 IDirectFBGL_data *data = ctx->DriverCtx;
594 #define INIT_PIXEL_PTR(P, X, Y) \
595 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X) * 3;
596 #define INC_PIXEL_PTR(P) P += 3
597 #define STORE_PIXEL(P, X, Y, S) \
598 P[0] = S[BCOMP]; P[1] = S[GCOMP]; P[2] = S[BCOMP]
599 #define FETCH_PIXEL(D, P) \
600 D[RCOMP] = P[2]; D[GCOMP] = P[1]; D[BCOMP] = P[0]; D[ACOMP] = 0xff
601
602 #include "swrast/s_spantemp.h"
603
604 /* RGB32 */
605 #define NAME(PREFIX) PREFIX##_RGB32
606 #define FORMAT GL_RGBA8
607 #define RB_TYPE GLubyte
608 #define SPAN_VARS \
609 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
610 #define INIT_PIXEL_PTR(P, X, Y) \
611 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
612 #define INC_PIXEL_PTR(P) P += 1
613 #define STORE_PIXEL(P, X, Y, S) \
614 *P = ( ((S[RCOMP]) << 16) | \
615 ((S[GCOMP]) << 8) | \
616 ((S[BCOMP]) ) )
617 #define FETCH_PIXEL(D, P) \
618 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
619 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
620 D[BCOMP] = ((*P & 0x000000ff) ); \
621 D[ACOMP] = 0xff
622
623 #include "swrast/s_spantemp.h"
624
625 /* ARGB */
626 #define NAME(PREFIX) PREFIX##_ARGB
627 #define FORMAT GL_RGBA8
628 #define RB_TYPE GLubyte
629 #define SPAN_VARS \
630 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
631 #define INIT_PIXEL_PTR(P, X, Y) \
632 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
633 #define INC_PIXEL_PTR(P) P += 1
634 #define STORE_PIXEL_RGB(P, X, Y, S) \
635 *P = ( 0xff000000 | \
636 ((S[RCOMP]) << 16) | \
637 ((S[GCOMP]) << 8) | \
638 ((S[BCOMP]) ) )
639 #define STORE_PIXEL(P, X, Y, S) \
640 *P = ( ((S[ACOMP]) << 24) | \
641 ((S[RCOMP]) << 16) | \
642 ((S[GCOMP]) << 8) | \
643 ((S[BCOMP]) ) )
644 #define FETCH_PIXEL(D, P) \
645 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
646 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
647 D[BCOMP] = ((*P & 0x000000ff) ); \
648 D[ACOMP] = ((*P & 0xff000000) >> 24)
649
650 #include "swrast/s_spantemp.h"
651
652 /* AiRGB */
653 #define NAME(PREFIX) PREFIX##_AiRGB
654 #define FORMAT GL_RGBA8
655 #define RB_TYPE GLubyte
656 #define SPAN_VARS \
657 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
658 #define INIT_PIXEL_PTR(P, X, Y) \
659 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
660 #define INC_PIXEL_PTR(P) P += 1
661 #define STORE_PIXEL_RGB(P, X, Y, S) \
662 *P = ( ((S[RCOMP]) << 16) | \
663 ((S[GCOMP]) << 8) | \
664 ((S[BCOMP]) ) )
665 #define STORE_PIXEL(P, X, Y, S) \
666 *P = ( (((S[ACOMP]) ^ 0xff) << 24) | \
667 (((S[RCOMP]) ) << 16) | \
668 (((S[GCOMP]) ) << 8) | \
669 (((S[BCOMP]) ) ) )
670 #define FETCH_PIXEL(D, P) \
671 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
672 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
673 D[BCOMP] = ((*P & 0x000000ff) ); \
674 D[ACOMP] = (((*P & 0xff000000) >> 24) ^ 0xff)
675
676 #include "swrast/s_spantemp.h"
677
678
679 /*****************************************************************************/
680
681 static bool
682 directfbgl_init_visual( GLvisual *visual,
683 DFBSurfacePixelFormat format )
684 {
685 GLboolean rgbFlag = GL_TRUE;
686 GLboolean dbFlag = GL_FALSE;
687 GLboolean stereoFlag = GL_FALSE;
688 GLint redBits = 0;
689 GLint blueBits = 0;
690 GLint greenBits = 0;
691 GLint alphaBits = 0;
692 GLint indexBits = 0;
693 GLint depthBits = 0;
694 GLint stencilBits = 0;
695 GLint accumRedBits = 0;
696 GLint accumGreenBits = 0;
697 GLint accumBlueBits = 0;
698 GLint accumAlphaBits = 0;
699 GLint numSamples = 0;
700
701 /* FIXME: LUT8 support. */
702 switch (format) {
703 case DSPF_RGB332:
704 redBits = 3;
705 greenBits = 3;
706 blueBits = 2;
707 break;
708 case DSPF_ARGB4444:
709 redBits = 4;
710 greenBits = 4;
711 blueBits = 4;
712 alphaBits = 4;
713 break;
714 case DSPF_ARGB2554:
715 redBits = 5;
716 greenBits = 5;
717 blueBits = 4;
718 alphaBits = 2;
719 break;
720 case DSPF_ARGB1555:
721 redBits = 5;
722 greenBits = 5;
723 blueBits = 5;
724 alphaBits = 1;
725 break;
726 case DSPF_RGB16:
727 redBits = 5;
728 greenBits = 6;
729 blueBits = 5;
730 break;
731 case DSPF_ARGB:
732 case DSPF_AiRGB:
733 alphaBits = 8;
734 case DSPF_RGB24:
735 case DSPF_RGB32:
736 redBits = 8;
737 greenBits = 8;
738 blueBits = 8;
739 break;
740 default:
741 D_WARN( "unsupported pixelformat" );
742 return false;
743 }
744
745 if (rgbFlag) {
746 accumRedBits = redBits;
747 accumGreenBits = greenBits;
748 accumBlueBits = blueBits;
749 accumAlphaBits = alphaBits;
750 depthBits = redBits + greenBits + blueBits;
751 stencilBits = alphaBits;
752 } else
753 depthBits = 8;
754
755 return _mesa_initialize_visual( visual,
756 rgbFlag, dbFlag, stereoFlag,
757 redBits, greenBits, blueBits, alphaBits,
758 indexBits, depthBits, stencilBits,
759 accumRedBits, accumGreenBits,
760 accumBlueBits, accumAlphaBits,
761 numSamples );
762 }
763
764 static bool
765 directfbgl_create_context( GLcontext *context,
766 GLframebuffer *framebuffer,
767 GLvisual *visual,
768 DFBSurfacePixelFormat format,
769 IDirectFBGL_data *data )
770 {
771 struct dd_function_table functions;
772
773 _mesa_initialize_framebuffer( framebuffer, visual );
774
775 _mesa_init_driver_functions( &functions );
776 functions.GetString = dfbGetString;
777 functions.UpdateState = dfbUpdateState;
778 functions.GetBufferSize = dfbGetBufferSize;
779 functions.Viewport = dfbSetViewport;
780 functions.Clear = dfbClear;
781
782 if (!_mesa_initialize_context( context, visual, NULL,
783 &functions, (void*) data )) {
784 D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" );
785 _mesa_free_framebuffer_data( framebuffer );
786 return false;
787 }
788
789 _swrast_CreateContext( context );
790 _vbo_CreateContext( context );
791 _tnl_CreateContext( context );
792 _swsetup_CreateContext( context );
793 _swsetup_Wakeup( context );
794
795 _mesa_init_renderbuffer( &data->render, 0 );
796 data->render.InternalFormat = GL_RGBA;
797 data->render._BaseFormat = GL_RGBA;
798 data->render.DataType = GL_UNSIGNED_BYTE;
799 data->render.Data = data->video.start;
800 data->render.Delete = dfbDeleteRenderbuffer;
801 data->render.AllocStorage = dfbRenderbufferStorage;
802
803 switch (format) {
804 case DSPF_RGB332:
805 data->render.GetRow = get_row_RGB332;
806 data->render.GetValues = get_values_RGB332;
807 data->render.PutRow = put_row_RGB332;
808 data->render.PutRowRGB = put_row_rgb_RGB332;
809 data->render.PutMonoRow = put_mono_row_RGB332;
810 data->render.PutValues = put_values_RGB332;
811 data->render.PutMonoValues = put_mono_values_RGB332;
812 break;
813 case DSPF_ARGB4444:
814 data->render.GetRow = get_row_ARGB4444;
815 data->render.GetValues = get_values_ARGB4444;
816 data->render.PutRow = put_row_ARGB4444;
817 data->render.PutRowRGB = put_row_rgb_ARGB4444;
818 data->render.PutMonoRow = put_mono_row_ARGB4444;
819 data->render.PutValues = put_values_ARGB4444;
820 data->render.PutMonoValues = put_mono_values_ARGB4444;
821 break;
822 case DSPF_ARGB2554:
823 data->render.GetRow = get_row_ARGB2554;
824 data->render.GetValues = get_values_ARGB2554;
825 data->render.PutRow = put_row_ARGB2554;
826 data->render.PutRowRGB = put_row_rgb_ARGB2554;
827 data->render.PutMonoRow = put_mono_row_ARGB2554;
828 data->render.PutValues = put_values_ARGB2554;
829 data->render.PutMonoValues = put_mono_values_ARGB2554;
830 break;
831 case DSPF_ARGB1555:
832 data->render.GetRow = get_row_ARGB1555;
833 data->render.GetValues = get_values_ARGB1555;
834 data->render.PutRow = put_row_ARGB1555;
835 data->render.PutRowRGB = put_row_rgb_ARGB1555;
836 data->render.PutMonoRow = put_mono_row_ARGB1555;
837 data->render.PutValues = put_values_ARGB1555;
838 data->render.PutMonoValues = put_mono_values_ARGB1555;
839 break;
840 case DSPF_RGB16:
841 data->render.GetRow = get_row_RGB16;
842 data->render.GetValues = get_values_RGB16;
843 data->render.PutRow = put_row_RGB16;
844 data->render.PutRowRGB = put_row_rgb_RGB16;
845 data->render.PutMonoRow = put_mono_row_RGB16;
846 data->render.PutValues = put_values_RGB16;
847 data->render.PutMonoValues = put_mono_values_RGB16;
848 break;
849 case DSPF_RGB24:
850 data->render.GetRow = get_row_RGB24;
851 data->render.GetValues = get_values_RGB24;
852 data->render.PutRow = put_row_RGB24;
853 data->render.PutRowRGB = put_row_rgb_RGB24;
854 data->render.PutMonoRow = put_mono_row_RGB24;
855 data->render.PutValues = put_values_RGB24;
856 data->render.PutMonoValues = put_mono_values_RGB24;
857 break;
858 case DSPF_RGB32:
859 data->render.GetRow = get_row_RGB32;
860 data->render.GetValues = get_values_RGB32;
861 data->render.PutRow = put_row_RGB32;
862 data->render.PutRowRGB = put_row_rgb_RGB32;
863 data->render.PutMonoRow = put_mono_row_RGB32;
864 data->render.PutValues = put_values_RGB32;
865 data->render.PutMonoValues = put_mono_values_RGB32;
866 break;
867 case DSPF_ARGB:
868 data->render.GetRow = get_row_ARGB;
869 data->render.GetValues = get_values_ARGB;
870 data->render.PutRow = put_row_ARGB;
871 data->render.PutRowRGB = put_row_rgb_ARGB;
872 data->render.PutMonoRow = put_mono_row_ARGB;
873 data->render.PutValues = put_values_ARGB;
874 data->render.PutMonoValues = put_mono_values_ARGB;
875 break;
876 case DSPF_AiRGB:
877 data->render.GetRow = get_row_AiRGB;
878 data->render.GetValues = get_values_AiRGB;
879 data->render.PutRow = put_row_AiRGB;
880 data->render.PutRowRGB = put_row_rgb_AiRGB;
881 data->render.PutMonoRow = put_mono_row_AiRGB;
882 data->render.PutValues = put_values_AiRGB;
883 data->render.PutMonoValues = put_mono_values_AiRGB;
884 break;
885 default:
886 D_BUG( "unexpected pixelformat" );
887 return false;
888 }
889
890 _mesa_add_renderbuffer( framebuffer, BUFFER_FRONT_LEFT, &data->render );
891
892 _mesa_add_soft_renderbuffers( framebuffer,
893 GL_FALSE,
894 visual->haveDepthBuffer,
895 visual->haveStencilBuffer,
896 visual->haveAccumBuffer,
897 GL_FALSE,
898 GL_FALSE );
899
900 TNL_CONTEXT( context )->Driver.RunPipeline = _tnl_run_pipeline;
901
902 _mesa_enable_sw_extensions( context );
903
904 return true;
905 }
906
907 static void
908 directfbgl_destroy_context( GLcontext *context,
909 GLframebuffer *framebuffer )
910 {
911 _mesa_free_framebuffer_data( framebuffer );
912 _mesa_notifyDestroy( context );
913 _mesa_free_context_data( context );
914 }
915