Merge branch 'master' into i915-unification
[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 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] &&
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 IDirectFBGL_data *data )
769 {
770 struct dd_function_table functions;
771
772 _mesa_initialize_framebuffer( framebuffer, visual );
773
774 _mesa_init_driver_functions( &functions );
775 functions.GetString = dfbGetString;
776 functions.UpdateState = dfbUpdateState;
777 functions.GetBufferSize = dfbGetBufferSize;
778 functions.Viewport = dfbSetViewport;
779 functions.Clear = dfbClear;
780
781 if (!_mesa_initialize_context( context, visual, NULL,
782 &functions, (void*) data )) {
783 D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" );
784 _mesa_free_framebuffer_data( framebuffer );
785 return false;
786 }
787
788 _swrast_CreateContext( context );
789 _vbo_CreateContext( context );
790 _tnl_CreateContext( context );
791 _swsetup_CreateContext( context );
792 _swsetup_Wakeup( context );
793
794 _mesa_init_renderbuffer( &data->render, 0 );
795 data->render.InternalFormat = GL_RGBA;
796 data->render._BaseFormat = GL_RGBA;
797 data->render.DataType = GL_UNSIGNED_BYTE;
798 data->render.Data = data->video.start;
799 data->render.Delete = dfbDeleteRenderbuffer;
800 data->render.AllocStorage = dfbRenderbufferStorage;
801
802 switch (data->format) {
803 case DSPF_RGB332:
804 data->render.GetRow = get_row_RGB332;
805 data->render.GetValues = get_values_RGB332;
806 data->render.PutRow = put_row_RGB332;
807 data->render.PutRowRGB = put_row_rgb_RGB332;
808 data->render.PutMonoRow = put_mono_row_RGB332;
809 data->render.PutValues = put_values_RGB332;
810 data->render.PutMonoValues = put_mono_values_RGB332;
811 break;
812 case DSPF_ARGB4444:
813 data->render.GetRow = get_row_ARGB4444;
814 data->render.GetValues = get_values_ARGB4444;
815 data->render.PutRow = put_row_ARGB4444;
816 data->render.PutRowRGB = put_row_rgb_ARGB4444;
817 data->render.PutMonoRow = put_mono_row_ARGB4444;
818 data->render.PutValues = put_values_ARGB4444;
819 data->render.PutMonoValues = put_mono_values_ARGB4444;
820 break;
821 case DSPF_ARGB2554:
822 data->render.GetRow = get_row_ARGB2554;
823 data->render.GetValues = get_values_ARGB2554;
824 data->render.PutRow = put_row_ARGB2554;
825 data->render.PutRowRGB = put_row_rgb_ARGB2554;
826 data->render.PutMonoRow = put_mono_row_ARGB2554;
827 data->render.PutValues = put_values_ARGB2554;
828 data->render.PutMonoValues = put_mono_values_ARGB2554;
829 break;
830 case DSPF_ARGB1555:
831 data->render.GetRow = get_row_ARGB1555;
832 data->render.GetValues = get_values_ARGB1555;
833 data->render.PutRow = put_row_ARGB1555;
834 data->render.PutRowRGB = put_row_rgb_ARGB1555;
835 data->render.PutMonoRow = put_mono_row_ARGB1555;
836 data->render.PutValues = put_values_ARGB1555;
837 data->render.PutMonoValues = put_mono_values_ARGB1555;
838 break;
839 case DSPF_RGB16:
840 data->render.GetRow = get_row_RGB16;
841 data->render.GetValues = get_values_RGB16;
842 data->render.PutRow = put_row_RGB16;
843 data->render.PutRowRGB = put_row_rgb_RGB16;
844 data->render.PutMonoRow = put_mono_row_RGB16;
845 data->render.PutValues = put_values_RGB16;
846 data->render.PutMonoValues = put_mono_values_RGB16;
847 break;
848 case DSPF_RGB24:
849 data->render.GetRow = get_row_RGB24;
850 data->render.GetValues = get_values_RGB24;
851 data->render.PutRow = put_row_RGB24;
852 data->render.PutRowRGB = put_row_rgb_RGB24;
853 data->render.PutMonoRow = put_mono_row_RGB24;
854 data->render.PutValues = put_values_RGB24;
855 data->render.PutMonoValues = put_mono_values_RGB24;
856 break;
857 case DSPF_RGB32:
858 data->render.GetRow = get_row_RGB32;
859 data->render.GetValues = get_values_RGB32;
860 data->render.PutRow = put_row_RGB32;
861 data->render.PutRowRGB = put_row_rgb_RGB32;
862 data->render.PutMonoRow = put_mono_row_RGB32;
863 data->render.PutValues = put_values_RGB32;
864 data->render.PutMonoValues = put_mono_values_RGB32;
865 break;
866 case DSPF_ARGB:
867 data->render.GetRow = get_row_ARGB;
868 data->render.GetValues = get_values_ARGB;
869 data->render.PutRow = put_row_ARGB;
870 data->render.PutRowRGB = put_row_rgb_ARGB;
871 data->render.PutMonoRow = put_mono_row_ARGB;
872 data->render.PutValues = put_values_ARGB;
873 data->render.PutMonoValues = put_mono_values_ARGB;
874 break;
875 case DSPF_AiRGB:
876 data->render.GetRow = get_row_AiRGB;
877 data->render.GetValues = get_values_AiRGB;
878 data->render.PutRow = put_row_AiRGB;
879 data->render.PutRowRGB = put_row_rgb_AiRGB;
880 data->render.PutMonoRow = put_mono_row_AiRGB;
881 data->render.PutValues = put_values_AiRGB;
882 data->render.PutMonoValues = put_mono_values_AiRGB;
883 break;
884 default:
885 D_BUG( "unexpected pixelformat" );
886 return false;
887 }
888
889 data->render.Width = data->width;
890 data->render.Height = data->height;
891
892 _mesa_add_renderbuffer( framebuffer, BUFFER_FRONT_LEFT, &data->render );
893
894 _mesa_add_soft_renderbuffers( framebuffer,
895 GL_FALSE,
896 visual->haveDepthBuffer,
897 visual->haveStencilBuffer,
898 visual->haveAccumBuffer,
899 GL_FALSE,
900 GL_FALSE );
901
902 TNL_CONTEXT( context )->Driver.RunPipeline = _tnl_run_pipeline;
903
904 _mesa_enable_sw_extensions( context );
905
906 return true;
907 }
908
909 static void
910 directfbgl_destroy_context( GLcontext *context,
911 GLframebuffer *framebuffer )
912 {
913 _swsetup_DestroyContext( context );
914 _swrast_DestroyContext( context );
915 _tnl_DestroyContext( context );
916 _vbo_DestroyContext( context );
917 //_mesa_free_framebuffer_data( framebuffer );
918 _mesa_free_context_data( context );
919 }
920