85a6f0367247ba73140daf5b5a8b6a03b55b2389
[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 "main/glheader.h"
40 #include "main/buffers.h"
41 #include "main/context.h"
42 #include "main/extensions.h"
43 #include "main/framebuffer.h"
44 #include "main/renderbuffer.h"
45 #include "main/imports.h"
46 #include "main/texformat.h"
47 #include "main/teximage.h"
48 #include "main/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 IDirectFBGL_data *data );
138 static void directfbgl_destroy_context( GLcontext *context,
139 GLframebuffer *framebuffer );
140
141 /******************************************************************************/
142
143
144 static void
145 IDirectFBGL_Mesa_Destruct( IDirectFBGL *thiz )
146 {
147 IDirectFBGL_data *data = (IDirectFBGL_data*) thiz->priv;
148
149 directfbgl_destroy_context( &data->context, &data->framebuffer );
150
151 if (data->surface)
152 data->surface->Release( data->surface );
153
154 DIRECT_DEALLOCATE_INTERFACE( thiz );
155
156 directfbgl_finish();
157 }
158
159 static DFBResult
160 IDirectFBGL_Mesa_AddRef( IDirectFBGL *thiz )
161 {
162 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
163
164 data->ref++;
165
166 return DFB_OK;
167 }
168
169 static DFBResult
170 IDirectFBGL_Mesa_Release( IDirectFBGL *thiz )
171 {
172 DIRECT_INTERFACE_GET_DATA( IDirectFBGL )
173
174 if (--data->ref == 0)
175 IDirectFBGL_Mesa_Destruct( thiz );
176
177 return DFB_OK;
178 }
179
180 static DFBResult
181 IDirectFBGL_Mesa_Lock( IDirectFBGL *thiz )
182 {
183 IDirectFBSurface *surface;
184 int width = 0;
185 int height = 0;
186 DFBResult ret;
187
188 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
189
190 if (data->locked) {
191 data->locked++;
192 return DFB_OK;
193 }
194
195 if (directfbgl_lock())
196 return DFB_LOCKED;
197
198 surface = data->surface;
199 surface->GetSize( surface, &width, &height );
200
201 ret = surface->Lock( surface, DSLF_READ | DSLF_WRITE,
202 (void*)&data->video.start, &data->video.pitch );
203 if (ret) {
204 D_ERROR( "DirectFBGL/Mesa: couldn't lock surface.\n" );
205 directfbgl_unlock();
206 return ret;
207 }
208 data->video.end = data->video.start + (height-1) * data->video.pitch;
209
210 data->render.Data = data->video.start;
211
212 _mesa_make_current( &data->context,
213 &data->framebuffer, &data->framebuffer );
214
215 if (data->width != width || data->height != height) {
216 _mesa_resize_framebuffer( &data->context,
217 &data->framebuffer, width, height );
218 data->width = width;
219 data->height = height;
220 }
221
222 data->locked++;
223
224 return DFB_OK;
225 }
226
227 static DFBResult
228 IDirectFBGL_Mesa_Unlock( IDirectFBGL *thiz )
229 {
230 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
231
232 if (!data->locked)
233 return DFB_OK;
234
235 if (--data->locked == 0) {
236 _mesa_make_current( NULL, NULL, NULL );
237
238 data->surface->Unlock( data->surface );
239
240 directfbgl_unlock();
241 }
242
243 return DFB_OK;
244 }
245
246 static DFBResult
247 IDirectFBGL_Mesa_GetAttributes( IDirectFBGL *thiz,
248 DFBGLAttributes *attributes )
249 {
250 DFBSurfaceCapabilities caps;
251 GLvisual *visual;
252
253 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
254
255 if (!attributes)
256 return DFB_INVARG;
257
258 data->surface->GetCapabilities( data->surface, &caps );
259
260 visual = &data->visual;
261
262 attributes->buffer_size = visual->rgbBits ? : visual->indexBits;
263 attributes->depth_size = visual->depthBits;
264 attributes->stencil_size = visual->stencilBits;
265 attributes->aux_buffers = visual->numAuxBuffers;
266 attributes->red_size = visual->redBits;
267 attributes->green_size = visual->greenBits;
268 attributes->blue_size = visual->blueBits;
269 attributes->alpha_size = visual->alphaBits;
270 attributes->accum_red_size = visual->accumRedBits;
271 attributes->accum_green_size = visual->accumGreenBits;
272 attributes->accum_blue_size = visual->accumBlueBits;
273 attributes->accum_alpha_size = visual->accumAlphaBits;
274 attributes->double_buffer = ((caps & DSCAPS_FLIPPING) != 0);
275 attributes->stereo = (visual->stereoMode != 0);
276
277 return DFB_OK;
278 }
279
280 #if DIRECTFBGL_INTERFACE_VERSION >= 1
281 static DFBResult
282 IDirectFBGL_Mesa_GetProcAddress( IDirectFBGL *thiz,
283 const char *name,
284 void **ret_address )
285 {
286 DIRECT_INTERFACE_GET_DATA( IDirectFBGL );
287
288 if (!name)
289 return DFB_INVARG;
290
291 if (!ret_address)
292 return DFB_INVARG;
293
294 *ret_address = _glapi_get_proc_address( name );
295
296 return (*ret_address) ? DFB_OK : DFB_UNSUPPORTED;
297 }
298 #endif
299
300
301 /* exported symbols */
302
303 static DFBResult
304 Probe( void *data )
305 {
306 return DFB_OK;
307 }
308
309 static DFBResult
310 Construct( IDirectFBGL *thiz, IDirectFBSurface *surface )
311 {
312 DFBResult ret;
313
314 /* Initialize global resources. */
315 if (directfbgl_init())
316 return DFB_INIT;
317
318 /* Allocate interface data. */
319 DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IDirectFBGL );
320
321 /* Initialize interface data. */
322 data->ref = 1;
323
324 /* Duplicate destination surface. */
325 ret = surface->GetSubSurface( surface, NULL, &data->surface );
326 if (ret) {
327 IDirectFBGL_Mesa_Destruct( thiz );
328 return ret;
329 }
330
331 data->surface->GetPixelFormat( data->surface, &data->format );
332 data->surface->GetSize( data->surface, &data->width, &data->height );
333
334 /* Configure visual. */
335 if (!directfbgl_init_visual( &data->visual, data->format )) {
336 D_ERROR( "DirectFBGL/Mesa: failed to initialize visual.\n" );
337 IDirectFBGL_Mesa_Destruct( thiz );
338 return DFB_UNSUPPORTED;
339 }
340
341 /* Create context. */
342 if (!directfbgl_create_context( &data->context,
343 &data->framebuffer,
344 &data->visual, 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][0] &&
411 ctx->Color.ColorMask[0][1] &&
412 ctx->Color.ColorMask[0][2] &&
413 ctx->Color.ColorMask[0][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) | ((*P & 0x0f00) >> 8); \
507 D[GCOMP] = ((*P & 0x00f0) ) | ((*P & 0x00f0) >> 4); \
508 D[BCOMP] = ((*P & 0x000f) << 4) | ((*P & 0x000f) ); \
509 D[ACOMP] = ((*P & 0xf000) >> 8) | ((*P & 0xf000) >> 12)
510
511 #include "swrast/s_spantemp.h"
512
513 /* RGB444 */
514 #define NAME(PREFIX) PREFIX##_RGB444
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(P, X, Y, S) \
523 *P = ( (((S[RCOMP]) & 0xf0) << 4) | \
524 (((S[GCOMP]) & 0xf0) ) | \
525 (((S[BCOMP]) & 0xf0) >> 4) )
526 #define FETCH_PIXEL(D, P) \
527 D[RCOMP] = ((*P & 0x0f00) >> 4) | ((*P & 0x0f00) >> 8); \
528 D[GCOMP] = ((*P & 0x00f0) ) | ((*P & 0x00f0) >> 4); \
529 D[BCOMP] = ((*P & 0x000f) << 4) | ((*P & 0x000f) ); \
530 D[ACOMP] = 0xff
531
532 #include "swrast/s_spantemp.h"
533
534 /* ARGB2554 */
535 #define NAME(PREFIX) PREFIX##_ARGB2554
536 #define FORMAT GL_RGBA8
537 #define RB_TYPE GLubyte
538 #define SPAN_VARS \
539 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
540 #define INIT_PIXEL_PTR(P, X, Y) \
541 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
542 #define INC_PIXEL_PTR(P) P += 1
543 #define STORE_PIXEL_RGB(P, X, Y, S) \
544 *P = ( 0xc000 | \
545 (((S[RCOMP]) & 0xf8) << 6) | \
546 (((S[GCOMP]) & 0xf8) << 1) | \
547 (((S[BCOMP]) & 0xf0) >> 4) )
548 #define STORE_PIXEL(P, X, Y, S) \
549 *P = ( (((S[ACOMP]) & 0xc0) << 8) | \
550 (((S[RCOMP]) & 0xf8) << 6) | \
551 (((S[GCOMP]) & 0xf8) << 1) | \
552 (((S[BCOMP]) & 0xf0) >> 4) )
553 #define FETCH_PIXEL(D, P) \
554 D[RCOMP] = ((*P & 0x3e00) >> 9); \
555 D[GCOMP] = ((*P & 0x01f0) >> 4); \
556 D[BCOMP] = ((*P & 0x000f) << 4); \
557 D[ACOMP] = ((*P & 0xc000) >> 14)
558
559 #include "swrast/s_spantemp.h"
560
561 /* ARGB1555 */
562 #define NAME(PREFIX) PREFIX##_ARGB1555
563 #define FORMAT GL_RGBA8
564 #define RB_TYPE GLubyte
565 #define SPAN_VARS \
566 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
567 #define INIT_PIXEL_PTR(P, X, Y) \
568 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
569 #define INC_PIXEL_PTR(P) P += 1
570 #define STORE_PIXEL_RGB(P, X, Y, S) \
571 *P = ( 0x8000 | \
572 (((S[RCOMP]) & 0xf8) << 7) | \
573 (((S[GCOMP]) & 0xf8) << 2) | \
574 (((S[BCOMP]) ) >> 3) )
575 #define STORE_PIXEL(P, X, Y, S) \
576 *P = ( (((S[ACOMP]) & 0x80) << 16) | \
577 (((S[RCOMP]) & 0xf8) << 7) | \
578 (((S[GCOMP]) & 0xf8) << 2) | \
579 (((S[BCOMP]) ) >> 3) )
580 #define FETCH_PIXEL(D, P) \
581 D[RCOMP] = ((*P & 0x7c00) >> 7) | ((*P & 0x7c00) >> 12); \
582 D[GCOMP] = ((*P & 0x03e0) >> 2) | ((*P & 0x03e0) >> 7); \
583 D[BCOMP] = ((*P & 0x001f) << 3) | ((*P & 0x001f) << 2); \
584 D[ACOMP] = ((*P & 0x8000) ? 0xff : 0)
585
586 #include "swrast/s_spantemp.h"
587
588 /* RGB555 */
589 #define NAME(PREFIX) PREFIX##_RGB555
590 #define FORMAT GL_RGBA8
591 #define RB_TYPE GLubyte
592 #define SPAN_VARS \
593 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
594 #define INIT_PIXEL_PTR(P, X, Y) \
595 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
596 #define INC_PIXEL_PTR(P) P += 1
597 #define STORE_PIXEL(P, X, Y, S) \
598 *P = ( (((S[RCOMP]) & 0xf8) << 7) | \
599 (((S[GCOMP]) & 0xf8) << 2) | \
600 (((S[BCOMP]) ) >> 3) )
601 #define FETCH_PIXEL(D, P) \
602 D[RCOMP] = ((*P & 0x7c00) >> 7) | ((*P & 0x7c00) >> 12); \
603 D[GCOMP] = ((*P & 0x03e0) >> 2) | ((*P & 0x03e0) >> 7); \
604 D[BCOMP] = ((*P & 0x001f) << 3) | ((*P & 0x001f) << 2); \
605 D[ACOMP] = 0xff
606
607 #include "swrast/s_spantemp.h"
608
609 /* RGB16 */
610 #define NAME(PREFIX) PREFIX##_RGB16
611 #define FORMAT GL_RGBA8
612 #define RB_TYPE GLubyte
613 #define SPAN_VARS \
614 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
615 #define INIT_PIXEL_PTR(P, X, Y) \
616 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
617 #define INC_PIXEL_PTR(P) P += 1
618 #define STORE_PIXEL(P, X, Y, S) \
619 *P = ( (((S[RCOMP]) & 0xf8) << 8) | \
620 (((S[GCOMP]) & 0xfc) << 3) | \
621 (((S[BCOMP]) ) >> 3) )
622 #define FETCH_PIXEL(D, P) \
623 D[RCOMP] = ((*P & 0xf800) >> 8) | ((*P & 0xf800) >> 13); \
624 D[GCOMP] = ((*P & 0x07e0) >> 3) | ((*P & 0x07e0) >> 9); \
625 D[BCOMP] = ((*P & 0x001f) << 3) | ((*P & 0x001f) >> 2); \
626 D[ACOMP] = 0xff
627
628 #include "swrast/s_spantemp.h"
629
630 /* RGB24 */
631 #define NAME(PREFIX) PREFIX##_RGB24
632 #define FORMAT GL_RGBA8
633 #define RB_TYPE GLubyte
634 #define SPAN_VARS \
635 IDirectFBGL_data *data = ctx->DriverCtx;
636 #define INIT_PIXEL_PTR(P, X, Y) \
637 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X) * 3;
638 #define INC_PIXEL_PTR(P) P += 3
639 #define STORE_PIXEL(P, X, Y, S) \
640 P[0] = S[BCOMP]; P[1] = S[GCOMP]; P[2] = S[BCOMP]
641 #define FETCH_PIXEL(D, P) \
642 D[RCOMP] = P[2]; D[GCOMP] = P[1]; D[BCOMP] = P[0]; D[ACOMP] = 0xff
643
644 #include "swrast/s_spantemp.h"
645
646 /* RGB32 */
647 #define NAME(PREFIX) PREFIX##_RGB32
648 #define FORMAT GL_RGBA8
649 #define RB_TYPE GLubyte
650 #define SPAN_VARS \
651 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
652 #define INIT_PIXEL_PTR(P, X, Y) \
653 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
654 #define INC_PIXEL_PTR(P) P += 1
655 #define STORE_PIXEL(P, X, Y, S) \
656 *P = ( ((S[RCOMP]) << 16) | \
657 ((S[GCOMP]) << 8) | \
658 ((S[BCOMP]) ) )
659 #define FETCH_PIXEL(D, P) \
660 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
661 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
662 D[BCOMP] = ((*P & 0x000000ff) ); \
663 D[ACOMP] = 0xff
664
665 #include "swrast/s_spantemp.h"
666
667 /* ARGB */
668 #define NAME(PREFIX) PREFIX##_ARGB
669 #define FORMAT GL_RGBA8
670 #define RB_TYPE GLubyte
671 #define SPAN_VARS \
672 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
673 #define INIT_PIXEL_PTR(P, X, Y) \
674 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
675 #define INC_PIXEL_PTR(P) P += 1
676 #define STORE_PIXEL_RGB(P, X, Y, S) \
677 *P = ( 0xff000000 | \
678 ((S[RCOMP]) << 16) | \
679 ((S[GCOMP]) << 8) | \
680 ((S[BCOMP]) ) )
681 #define STORE_PIXEL(P, X, Y, S) \
682 *P = ( ((S[ACOMP]) << 24) | \
683 ((S[RCOMP]) << 16) | \
684 ((S[GCOMP]) << 8) | \
685 ((S[BCOMP]) ) )
686 #define FETCH_PIXEL(D, P) \
687 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
688 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
689 D[BCOMP] = ((*P & 0x000000ff) ); \
690 D[ACOMP] = ((*P & 0xff000000) >> 24)
691
692 #include "swrast/s_spantemp.h"
693
694 /* AiRGB */
695 #define NAME(PREFIX) PREFIX##_AiRGB
696 #define FORMAT GL_RGBA8
697 #define RB_TYPE GLubyte
698 #define SPAN_VARS \
699 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
700 #define INIT_PIXEL_PTR(P, X, Y) \
701 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
702 #define INC_PIXEL_PTR(P) P += 1
703 #define STORE_PIXEL_RGB(P, X, Y, S) \
704 *P = ( ((S[RCOMP]) << 16) | \
705 ((S[GCOMP]) << 8) | \
706 ((S[BCOMP]) ) )
707 #define STORE_PIXEL(P, X, Y, S) \
708 *P = ( (((S[ACOMP]) ^ 0xff) << 24) | \
709 (((S[RCOMP]) ) << 16) | \
710 (((S[GCOMP]) ) << 8) | \
711 (((S[BCOMP]) ) ) )
712 #define FETCH_PIXEL(D, P) \
713 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
714 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
715 D[BCOMP] = ((*P & 0x000000ff) ); \
716 D[ACOMP] = (((*P & 0xff000000) >> 24) ^ 0xff)
717
718 #include "swrast/s_spantemp.h"
719
720
721 /*****************************************************************************/
722
723 static bool
724 directfbgl_init_visual( GLvisual *visual,
725 DFBSurfacePixelFormat format )
726 {
727 GLboolean rgbFlag = GL_TRUE;
728 GLboolean dbFlag = GL_FALSE;
729 GLboolean stereoFlag = GL_FALSE;
730 GLint redBits = 0;
731 GLint blueBits = 0;
732 GLint greenBits = 0;
733 GLint alphaBits = 0;
734 GLint indexBits = 0;
735 GLint depthBits = 0;
736 GLint stencilBits = 0;
737 GLint accumRedBits = 0;
738 GLint accumGreenBits = 0;
739 GLint accumBlueBits = 0;
740 GLint accumAlphaBits = 0;
741 GLint numSamples = 0;
742
743 /* FIXME: LUT8 support. */
744 switch (format) {
745 case DSPF_RGB332:
746 redBits = 3;
747 greenBits = 3;
748 blueBits = 2;
749 break;
750 case DSPF_ARGB4444:
751 alphaBits = 4;
752 case DSPF_RGB444:
753 redBits = 4;
754 greenBits = 4;
755 blueBits = 4;
756 break;
757 case DSPF_ARGB2554:
758 alphaBits = 2;
759 redBits = 5;
760 greenBits = 5;
761 blueBits = 4;
762 break;
763 case DSPF_ARGB1555:
764 alphaBits = 1;
765 case DSPF_RGB555:
766 redBits = 5;
767 greenBits = 5;
768 blueBits = 5;
769 break;
770 case DSPF_RGB16:
771 redBits = 5;
772 greenBits = 6;
773 blueBits = 5;
774 break;
775 case DSPF_ARGB:
776 case DSPF_AiRGB:
777 alphaBits = 8;
778 case DSPF_RGB24:
779 case DSPF_RGB32:
780 redBits = 8;
781 greenBits = 8;
782 blueBits = 8;
783 break;
784 default:
785 D_WARN( "unsupported pixelformat" );
786 return false;
787 }
788
789 if (rgbFlag) {
790 accumRedBits = redBits;
791 accumGreenBits = greenBits;
792 accumBlueBits = blueBits;
793 accumAlphaBits = alphaBits;
794 depthBits = redBits + greenBits + blueBits;
795 stencilBits = alphaBits;
796 } else
797 depthBits = 8;
798
799 return _mesa_initialize_visual( visual,
800 rgbFlag, dbFlag, stereoFlag,
801 redBits, greenBits, blueBits, alphaBits,
802 indexBits, depthBits, stencilBits,
803 accumRedBits, accumGreenBits,
804 accumBlueBits, accumAlphaBits,
805 numSamples );
806 }
807
808 static bool
809 directfbgl_create_context( GLcontext *context,
810 GLframebuffer *framebuffer,
811 GLvisual *visual,
812 IDirectFBGL_data *data )
813 {
814 struct dd_function_table functions;
815
816 _mesa_initialize_window_framebuffer( framebuffer, visual );
817
818 _mesa_init_driver_functions( &functions );
819 functions.GetString = dfbGetString;
820 functions.UpdateState = dfbUpdateState;
821 functions.GetBufferSize = dfbGetBufferSize;
822 functions.Viewport = dfbSetViewport;
823 functions.Clear = dfbClear;
824
825 if (!_mesa_initialize_context( context, visual, NULL,
826 &functions, (void*) data )) {
827 D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" );
828 _mesa_free_framebuffer_data( framebuffer );
829 return false;
830 }
831
832 _swrast_CreateContext( context );
833 _vbo_CreateContext( context );
834 _tnl_CreateContext( context );
835 _swsetup_CreateContext( context );
836 _swsetup_Wakeup( context );
837
838 _mesa_init_renderbuffer( &data->render, 0 );
839 data->render.InternalFormat = GL_RGBA;
840 data->render._BaseFormat = GL_RGBA;
841 data->render.DataType = GL_UNSIGNED_BYTE;
842 data->render.Data = data->video.start;
843 data->render.Delete = dfbDeleteRenderbuffer;
844 data->render.AllocStorage = dfbRenderbufferStorage;
845
846 switch (data->format) {
847 case DSPF_RGB332:
848 data->render.GetRow = get_row_RGB332;
849 data->render.GetValues = get_values_RGB332;
850 data->render.PutRow = put_row_RGB332;
851 data->render.PutRowRGB = put_row_rgb_RGB332;
852 data->render.PutMonoRow = put_mono_row_RGB332;
853 data->render.PutValues = put_values_RGB332;
854 data->render.PutMonoValues = put_mono_values_RGB332;
855 break;
856 case DSPF_ARGB4444:
857 data->render.GetRow = get_row_ARGB4444;
858 data->render.GetValues = get_values_ARGB4444;
859 data->render.PutRow = put_row_ARGB4444;
860 data->render.PutRowRGB = put_row_rgb_ARGB4444;
861 data->render.PutMonoRow = put_mono_row_ARGB4444;
862 data->render.PutValues = put_values_ARGB4444;
863 data->render.PutMonoValues = put_mono_values_ARGB4444;
864 break;
865 case DSPF_RGB444:
866 data->render.GetRow = get_row_RGB444;
867 data->render.GetValues = get_values_RGB444;
868 data->render.PutRow = put_row_RGB444;
869 data->render.PutRowRGB = put_row_rgb_RGB444;
870 data->render.PutMonoRow = put_mono_row_RGB444;
871 data->render.PutValues = put_values_RGB444;
872 data->render.PutMonoValues = put_mono_values_RGB444;
873 break;
874 case DSPF_ARGB2554:
875 data->render.GetRow = get_row_ARGB2554;
876 data->render.GetValues = get_values_ARGB2554;
877 data->render.PutRow = put_row_ARGB2554;
878 data->render.PutRowRGB = put_row_rgb_ARGB2554;
879 data->render.PutMonoRow = put_mono_row_ARGB2554;
880 data->render.PutValues = put_values_ARGB2554;
881 data->render.PutMonoValues = put_mono_values_ARGB2554;
882 break;
883 case DSPF_ARGB1555:
884 data->render.GetRow = get_row_ARGB1555;
885 data->render.GetValues = get_values_ARGB1555;
886 data->render.PutRow = put_row_ARGB1555;
887 data->render.PutRowRGB = put_row_rgb_ARGB1555;
888 data->render.PutMonoRow = put_mono_row_ARGB1555;
889 data->render.PutValues = put_values_ARGB1555;
890 data->render.PutMonoValues = put_mono_values_ARGB1555;
891 break;
892 case DSPF_RGB555:
893 data->render.GetRow = get_row_RGB555;
894 data->render.GetValues = get_values_RGB555;
895 data->render.PutRow = put_row_RGB555;
896 data->render.PutRowRGB = put_row_rgb_RGB555;
897 data->render.PutMonoRow = put_mono_row_RGB555;
898 data->render.PutValues = put_values_RGB555;
899 data->render.PutMonoValues = put_mono_values_RGB555;
900 break;
901 case DSPF_RGB16:
902 data->render.GetRow = get_row_RGB16;
903 data->render.GetValues = get_values_RGB16;
904 data->render.PutRow = put_row_RGB16;
905 data->render.PutRowRGB = put_row_rgb_RGB16;
906 data->render.PutMonoRow = put_mono_row_RGB16;
907 data->render.PutValues = put_values_RGB16;
908 data->render.PutMonoValues = put_mono_values_RGB16;
909 break;
910 case DSPF_RGB24:
911 data->render.GetRow = get_row_RGB24;
912 data->render.GetValues = get_values_RGB24;
913 data->render.PutRow = put_row_RGB24;
914 data->render.PutRowRGB = put_row_rgb_RGB24;
915 data->render.PutMonoRow = put_mono_row_RGB24;
916 data->render.PutValues = put_values_RGB24;
917 data->render.PutMonoValues = put_mono_values_RGB24;
918 break;
919 case DSPF_RGB32:
920 data->render.GetRow = get_row_RGB32;
921 data->render.GetValues = get_values_RGB32;
922 data->render.PutRow = put_row_RGB32;
923 data->render.PutRowRGB = put_row_rgb_RGB32;
924 data->render.PutMonoRow = put_mono_row_RGB32;
925 data->render.PutValues = put_values_RGB32;
926 data->render.PutMonoValues = put_mono_values_RGB32;
927 break;
928 case DSPF_ARGB:
929 data->render.GetRow = get_row_ARGB;
930 data->render.GetValues = get_values_ARGB;
931 data->render.PutRow = put_row_ARGB;
932 data->render.PutRowRGB = put_row_rgb_ARGB;
933 data->render.PutMonoRow = put_mono_row_ARGB;
934 data->render.PutValues = put_values_ARGB;
935 data->render.PutMonoValues = put_mono_values_ARGB;
936 break;
937 case DSPF_AiRGB:
938 data->render.GetRow = get_row_AiRGB;
939 data->render.GetValues = get_values_AiRGB;
940 data->render.PutRow = put_row_AiRGB;
941 data->render.PutRowRGB = put_row_rgb_AiRGB;
942 data->render.PutMonoRow = put_mono_row_AiRGB;
943 data->render.PutValues = put_values_AiRGB;
944 data->render.PutMonoValues = put_mono_values_AiRGB;
945 break;
946 default:
947 D_BUG( "unexpected pixelformat" );
948 return false;
949 }
950
951 data->render.Width = data->width;
952 data->render.Height = data->height;
953
954 _mesa_add_renderbuffer( framebuffer, BUFFER_FRONT_LEFT, &data->render );
955
956 _mesa_add_soft_renderbuffers( framebuffer,
957 GL_FALSE,
958 visual->haveDepthBuffer,
959 visual->haveStencilBuffer,
960 visual->haveAccumBuffer,
961 GL_FALSE,
962 GL_FALSE );
963
964 TNL_CONTEXT( context )->Driver.RunPipeline = _tnl_run_pipeline;
965
966 _mesa_enable_sw_extensions( context );
967
968 return true;
969 }
970
971 static void
972 directfbgl_destroy_context( GLcontext *context,
973 GLframebuffer *framebuffer )
974 {
975 _swsetup_DestroyContext( context );
976 _swrast_DestroyContext( context );
977 _tnl_DestroyContext( context );
978 _vbo_DestroyContext( context );
979 //_mesa_free_framebuffer_data( framebuffer );
980 _mesa_free_context_data( context );
981 }
982