Add reporting of damage by DRI drivers when the extension support is available.
[mesa.git] / src / mesa / drivers / directfb / idirectfbgl_mesa.c
1 /*
2 * Copyright (C) 2004-2006 Claudio Ciccani <klan@users.sf.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 *
18 * Based on glfbdev.c, written by Brian Paul.
19 *
20 */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25
26 #include <pthread.h>
27
28 #include <directfb.h>
29 #include <directfb_version.h>
30
31 #include <directfbgl.h>
32
33 #include <direct/mem.h>
34 #include <direct/messages.h>
35 #include <direct/interface.h>
36
37 #undef CLAMP
38 #include "glheader.h"
39 #include "buffers.h"
40 #include "context.h"
41 #include "extensions.h"
42 #include "framebuffer.h"
43 #include "renderbuffer.h"
44 #include "imports.h"
45 #include "texformat.h"
46 #include "teximage.h"
47 #include "texstore.h"
48 #include "array_cache/acache.h"
49 #include "swrast/swrast.h"
50 #include "swrast_setup/swrast_setup.h"
51 #include "tnl/tnl.h"
52 #include "tnl/t_context.h"
53 #include "tnl/t_pipeline.h"
54 #include "drivers/common/driverfuncs.h"
55
56
57 #define VERSION_CODE( M, m, r ) (((M) * 1000) + ((m) * 100) + ((r)))
58 #define DIRECTFB_VERSION_CODE VERSION_CODE( DIRECTFB_MAJOR_VERSION, \
59 DIRECTFB_MINOR_VERSION, \
60 DIRECTFB_MICRO_VERSION )
61
62
63 static DFBResult
64 Probe( void *data );
65
66 static DFBResult
67 Construct( IDirectFBGL *thiz,
68 IDirectFBSurface *surface );
69
70 #include <direct/interface_implementation.h>
71
72 DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBGL, Mesa )
73
74 /*
75 * private data struct of IDirectFBGL
76 */
77 typedef struct {
78 int ref; /* reference counter */
79
80 int locked;
81
82 IDirectFBSurface *surface;
83 DFBSurfacePixelFormat format;
84 int width;
85 int height;
86
87 struct {
88 GLubyte *start;
89 GLubyte *end;
90 int pitch;
91 } video;
92
93 GLvisual visual;
94 GLframebuffer framebuffer;
95 GLcontext context;
96 struct gl_renderbuffer render;
97 } IDirectFBGL_data;
98
99 /******************************************************************************/
100
101 static pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER;
102 static unsigned int global_ref = 0;
103
104 static inline int directfbgl_init( void )
105 {
106 pthread_mutexattr_t attr;
107 int ret;
108
109 if (global_ref++)
110 return 0;
111
112 pthread_mutexattr_init( &attr );
113 pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK );
114 ret = pthread_mutex_init( &global_lock, &attr );
115 pthread_mutexattr_destroy( &attr );
116
117 return ret;
118 }
119
120 static inline void directfbgl_finish( void )
121 {
122 if (--global_ref == 0)
123 pthread_mutex_destroy( &global_lock );
124 }
125
126 #define directfbgl_lock() pthread_mutex_lock( &global_lock )
127 #define directfbgl_unlock() pthread_mutex_unlock( &global_lock )
128
129 /******************************************************************************/
130
131 static bool directfbgl_init_visual ( GLvisual *visual,
132 DFBSurfacePixelFormat format );
133 static bool directfbgl_create_context ( GLcontext *context,
134 GLframebuffer *framebuffer,
135 GLvisual *visual,
136 DFBSurfacePixelFormat format,
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, &data->framebuffer,
343 &data->visual, data->format, data )) {
344 D_ERROR( "DirectFBGL/Mesa: failed to create context.\n" );
345 IDirectFBGL_Mesa_Destruct( thiz );
346 return DFB_UNSUPPORTED;
347 }
348
349 /* Assign interface pointers. */
350 thiz->AddRef = IDirectFBGL_Mesa_AddRef;
351 thiz->Release = IDirectFBGL_Mesa_Release;
352 thiz->Lock = IDirectFBGL_Mesa_Lock;
353 thiz->Unlock = IDirectFBGL_Mesa_Unlock;
354 thiz->GetAttributes = IDirectFBGL_Mesa_GetAttributes;
355 #if DIRECTFBGL_INTERFACE_VERSION >= 1
356 thiz->GetProcAddress = IDirectFBGL_Mesa_GetProcAddress;
357 #endif
358
359 return DFB_OK;
360 }
361
362
363 /***************************** Driver functions ******************************/
364
365 static const GLubyte*
366 dfbGetString( GLcontext *ctx, GLenum pname )
367 {
368 return NULL;
369 }
370
371 static void
372 dfbUpdateState( GLcontext *ctx, GLuint new_state )
373 {
374 _swrast_InvalidateState( ctx, new_state );
375 _swsetup_InvalidateState( ctx, new_state );
376 _ac_InvalidateState( ctx, new_state );
377 _tnl_InvalidateState( ctx, new_state );
378 }
379
380 static void
381 dfbGetBufferSize( GLframebuffer *buffer, GLuint *width, GLuint *height )
382 {
383 GLcontext *ctx = _mesa_get_current_context();
384 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
385
386 *width = (GLuint) data->width;
387 *height = (GLuint) data->height;
388 }
389
390 /**
391 * We only implement this function as a mechanism to check if the
392 * framebuffer size has changed (and update corresponding state).
393 */
394 static void
395 dfbSetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h )
396 {
397 /* Nothing to do (the surface can't be resized while it's locked). */
398 return;
399 }
400
401 static void
402 dfbClear( GLcontext *ctx, GLbitfield mask )
403 {
404 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
405
406 #define BUFFER_BIT_MASK (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT | \
407 BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT )
408 if (mask & BUFFER_BIT_MASK &&
409 ctx->Color.ColorMask[0] &&
410 ctx->Color.ColorMask[1] &&
411 ctx->Color.ColorMask[2] &&
412 ctx->Color.ColorMask[3])
413 {
414 DFBRegion clip;
415 GLubyte a, r, g, b;
416
417 UNCLAMPED_FLOAT_TO_UBYTE( a, ctx->Color.ClearColor[ACOMP] );
418 UNCLAMPED_FLOAT_TO_UBYTE( r, ctx->Color.ClearColor[RCOMP] );
419 UNCLAMPED_FLOAT_TO_UBYTE( g, ctx->Color.ClearColor[GCOMP] );
420 UNCLAMPED_FLOAT_TO_UBYTE( b, ctx->Color.ClearColor[BCOMP] );
421
422 clip.x1 = ctx->DrawBuffer->_Xmin;
423 clip.y1 = ctx->DrawBuffer->_Ymin;
424 clip.x2 = ctx->DrawBuffer->_Xmax - 1;
425 clip.y2 = ctx->DrawBuffer->_Ymax - 1;
426 data->surface->SetClip( data->surface, &clip );
427
428 data->surface->Unlock( data->surface );
429
430 data->surface->Clear( data->surface, r, g, b, a );
431
432 data->surface->Lock( data->surface, DSLF_READ | DSLF_WRITE,
433 (void*)&data->video.start, &data->video.pitch );
434 data->video.end = data->video.start + (data->height-1) * data->video.pitch;
435 data->render.Data = data->video.start;
436
437 mask &= ~BUFFER_BIT_MASK;
438 }
439 #undef BUFFER_BIT_MASK
440
441 if (mask)
442 _swrast_Clear( ctx, mask );
443 }
444
445
446 /************************ RenderBuffer functions *****************************/
447
448 static void
449 dfbDeleteRenderbuffer( struct gl_renderbuffer *render )
450 {
451 return;
452 }
453
454 static GLboolean
455 dfbRenderbufferStorage( GLcontext *ctx, struct gl_renderbuffer *render,
456 GLenum internalFormat, GLuint width, GLuint height )
457 {
458 return GL_TRUE;
459 }
460
461
462 /***************************** Span functions ********************************/
463
464 /* RGB332 */
465 #define NAME(PREFIX) PREFIX##_RGB332
466 #define FORMAT GL_RGBA8
467 #define RB_TYPE GLubyte
468 #define SPAN_VARS \
469 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
470 #define INIT_PIXEL_PTR(P, X, Y) \
471 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X);
472 #define INC_PIXEL_PTR(P) P += 1
473 #define STORE_PIXEL(P, X, Y, S) \
474 *P = ( (((S[RCOMP]) & 0xe0) ) | \
475 (((S[GCOMP]) & 0xe0) >> 3) | \
476 (((S[BCOMP]) ) >> 6) )
477 #define FETCH_PIXEL(D, P) \
478 D[RCOMP] = ((*P & 0xe0) ); \
479 D[GCOMP] = ((*P & 0x1c) << 3); \
480 D[BCOMP] = ((*P & 0x03) << 6); \
481 D[ACOMP] = 0xff
482
483 #include "swrast/s_spantemp.h"
484
485 /* ARGB4444 */
486 #define NAME(PREFIX) PREFIX##_ARGB4444
487 #define FORMAT GL_RGBA8
488 #define RB_TYPE GLubyte
489 #define SPAN_VARS \
490 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
491 #define INIT_PIXEL_PTR(P, X, Y) \
492 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
493 #define INC_PIXEL_PTR(P) P += 1
494 #define STORE_PIXEL_RGB(P, X, Y, S) \
495 *P = ( 0xf000 | \
496 (((S[RCOMP]) & 0xf0) << 4) | \
497 (((S[GCOMP]) & 0xf0) ) | \
498 (((S[BCOMP]) & 0xf0) >> 4) )
499 #define STORE_PIXEL(P, X, Y, S) \
500 *P = ( (((S[ACOMP]) & 0xf0) << 8) | \
501 (((S[RCOMP]) & 0xf0) << 4) | \
502 (((S[GCOMP]) & 0xf0) ) | \
503 (((S[BCOMP]) & 0xf0) >> 4) )
504 #define FETCH_PIXEL(D, P) \
505 D[RCOMP] = ((*P & 0x0f00) >> 4); \
506 D[GCOMP] = ((*P & 0x00f0) ); \
507 D[BCOMP] = ((*P & 0x000f) << 4); \
508 D[ACOMP] = ((*P & 0xf000) >> 8)
509
510 #include "swrast/s_spantemp.h"
511
512 /* ARGB2554 */
513 #define NAME(PREFIX) PREFIX##_ARGB2554
514 #define FORMAT GL_RGBA8
515 #define RB_TYPE GLubyte
516 #define SPAN_VARS \
517 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
518 #define INIT_PIXEL_PTR(P, X, Y) \
519 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
520 #define INC_PIXEL_PTR(P) P += 1
521 #define STORE_PIXEL_RGB(P, X, Y, S) \
522 *P = ( 0xc000 | \
523 (((S[RCOMP]) & 0xf8) << 6) | \
524 (((S[GCOMP]) & 0xf8) << 1) | \
525 (((S[BCOMP]) & 0xf0) >> 4) )
526 #define STORE_PIXEL(P, X, Y, S) \
527 *P = ( (((S[ACOMP]) & 0xc0) << 8) | \
528 (((S[RCOMP]) & 0xf8) << 6) | \
529 (((S[GCOMP]) & 0xf8) << 1) | \
530 (((S[BCOMP]) & 0xf0) >> 4) )
531 #define FETCH_PIXEL(D, P) \
532 D[RCOMP] = ((*P & 0x3e00) >> 9); \
533 D[GCOMP] = ((*P & 0x01f0) >> 4); \
534 D[BCOMP] = ((*P & 0x000f) << 4); \
535 D[ACOMP] = ((*P & 0xc000) >> 14)
536
537 #include "swrast/s_spantemp.h"
538
539 /* ARGB1555 */
540 #define NAME(PREFIX) PREFIX##_ARGB1555
541 #define FORMAT GL_RGBA8
542 #define RB_TYPE GLubyte
543 #define SPAN_VARS \
544 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
545 #define INIT_PIXEL_PTR(P, X, Y) \
546 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
547 #define INC_PIXEL_PTR(P) P += 1
548 #define STORE_PIXEL_RGB(P, X, Y, S) \
549 *P = ( 0x8000 | \
550 (((S[RCOMP]) & 0xf8) << 7) | \
551 (((S[GCOMP]) & 0xf8) << 2) | \
552 (((S[BCOMP]) ) >> 3) )
553 #define STORE_PIXEL(P, X, Y, S) \
554 *P = ( (((S[ACOMP]) & 0x80) << 16) | \
555 (((S[RCOMP]) & 0xf8) << 7) | \
556 (((S[GCOMP]) & 0xf8) << 2) | \
557 (((S[BCOMP]) ) >> 3) )
558 #define FETCH_PIXEL(D, P) \
559 D[RCOMP] = ((*P & 0x7c00) >> 7); \
560 D[GCOMP] = ((*P & 0x03e0) >> 2); \
561 D[BCOMP] = ((*P & 0x001f) << 3); \
562 D[ACOMP] = ((*P & 0x8000) ? 0xff : 0)
563
564 #include "swrast/s_spantemp.h"
565
566 /* RGB16 */
567 #define NAME(PREFIX) PREFIX##_RGB16
568 #define FORMAT GL_RGBA8
569 #define RB_TYPE GLubyte
570 #define SPAN_VARS \
571 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
572 #define INIT_PIXEL_PTR(P, X, Y) \
573 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
574 #define INC_PIXEL_PTR(P) P += 1
575 #define STORE_PIXEL(P, X, Y, S) \
576 *P = ( (((S[RCOMP]) & 0xf8) << 8) | \
577 (((S[GCOMP]) & 0xfc) << 3) | \
578 (((S[BCOMP]) ) >> 3) )
579 #define FETCH_PIXEL(D, P) \
580 D[RCOMP] = ((*P & 0xf800) >> 8); \
581 D[GCOMP] = ((*P & 0x07e0) >> 3); \
582 D[BCOMP] = ((*P & 0x001f) << 3); \
583 D[ACOMP] = 0xff
584
585 #include "swrast/s_spantemp.h"
586
587 /* RGB24 */
588 #define NAME(PREFIX) PREFIX##_RGB24
589 #define FORMAT GL_RGBA8
590 #define RB_TYPE GLubyte
591 #define SPAN_VARS \
592 IDirectFBGL_data *data = ctx->DriverCtx;
593 #define INIT_PIXEL_PTR(P, X, Y) \
594 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X) * 3;
595 #define INC_PIXEL_PTR(P) P += 3
596 #define STORE_PIXEL(P, X, Y, S) \
597 P[0] = S[BCOMP]; P[1] = S[GCOMP]; P[2] = S[BCOMP]
598 #define FETCH_PIXEL(D, P) \
599 D[RCOMP] = P[2]; D[GCOMP] = P[1]; D[BCOMP] = P[0]; D[ACOMP] = 0xff
600
601 #include "swrast/s_spantemp.h"
602
603 /* RGB32 */
604 #define NAME(PREFIX) PREFIX##_RGB32
605 #define FORMAT GL_RGBA8
606 #define RB_TYPE GLubyte
607 #define SPAN_VARS \
608 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
609 #define INIT_PIXEL_PTR(P, X, Y) \
610 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
611 #define INC_PIXEL_PTR(P) P += 1
612 #define STORE_PIXEL(P, X, Y, S) \
613 *P = ( ((S[RCOMP]) << 16) | \
614 ((S[GCOMP]) << 8) | \
615 ((S[BCOMP]) ) )
616 #define FETCH_PIXEL(D, P) \
617 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
618 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
619 D[BCOMP] = ((*P & 0x000000ff) ); \
620 D[ACOMP] = 0xff
621
622 #include "swrast/s_spantemp.h"
623
624 /* ARGB */
625 #define NAME(PREFIX) PREFIX##_ARGB
626 #define FORMAT GL_RGBA8
627 #define RB_TYPE GLubyte
628 #define SPAN_VARS \
629 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
630 #define INIT_PIXEL_PTR(P, X, Y) \
631 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
632 #define INC_PIXEL_PTR(P) P += 1
633 #define STORE_PIXEL_RGB(P, X, Y, S) \
634 *P = ( 0xff000000 | \
635 ((S[RCOMP]) << 16) | \
636 ((S[GCOMP]) << 8) | \
637 ((S[BCOMP]) ) )
638 #define STORE_PIXEL(P, X, Y, S) \
639 *P = ( ((S[ACOMP]) << 24) | \
640 ((S[RCOMP]) << 16) | \
641 ((S[GCOMP]) << 8) | \
642 ((S[BCOMP]) ) )
643 #define FETCH_PIXEL(D, P) \
644 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
645 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
646 D[BCOMP] = ((*P & 0x000000ff) ); \
647 D[ACOMP] = ((*P & 0xff000000) >> 24)
648
649 #include "swrast/s_spantemp.h"
650
651 /* AiRGB */
652 #define NAME(PREFIX) PREFIX##_AiRGB
653 #define FORMAT GL_RGBA8
654 #define RB_TYPE GLubyte
655 #define SPAN_VARS \
656 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
657 #define INIT_PIXEL_PTR(P, X, Y) \
658 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
659 #define INC_PIXEL_PTR(P) P += 1
660 #define STORE_PIXEL_RGB(P, X, Y, S) \
661 *P = ( ((S[RCOMP]) << 16) | \
662 ((S[GCOMP]) << 8) | \
663 ((S[BCOMP]) ) )
664 #define STORE_PIXEL(P, X, Y, S) \
665 *P = ( (((S[ACOMP]) ^ 0xff) << 24) | \
666 (((S[RCOMP]) ) << 16) | \
667 (((S[GCOMP]) ) << 8) | \
668 (((S[BCOMP]) ) ) )
669 #define FETCH_PIXEL(D, P) \
670 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
671 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
672 D[BCOMP] = ((*P & 0x000000ff) ); \
673 D[ACOMP] = (((*P & 0xff000000) >> 24) ^ 0xff)
674
675 #include "swrast/s_spantemp.h"
676
677
678 /*****************************************************************************/
679
680 static bool
681 directfbgl_init_visual( GLvisual *visual,
682 DFBSurfacePixelFormat format )
683 {
684 GLboolean rgbFlag = GL_TRUE;
685 GLboolean dbFlag = GL_FALSE;
686 GLboolean stereoFlag = GL_FALSE;
687 GLint redBits = 0;
688 GLint blueBits = 0;
689 GLint greenBits = 0;
690 GLint alphaBits = 0;
691 GLint indexBits = 0;
692 GLint depthBits = 0;
693 GLint stencilBits = 0;
694 GLint accumRedBits = 0;
695 GLint accumGreenBits = 0;
696 GLint accumBlueBits = 0;
697 GLint accumAlphaBits = 0;
698 GLint numSamples = 0;
699
700 /* FIXME: LUT8 support. */
701 switch (format) {
702 case DSPF_RGB332:
703 redBits = 3;
704 greenBits = 3;
705 blueBits = 2;
706 break;
707 case DSPF_ARGB4444:
708 redBits = 4;
709 greenBits = 4;
710 blueBits = 4;
711 alphaBits = 4;
712 break;
713 case DSPF_ARGB2554:
714 redBits = 5;
715 greenBits = 5;
716 blueBits = 4;
717 alphaBits = 2;
718 break;
719 case DSPF_ARGB1555:
720 redBits = 5;
721 greenBits = 5;
722 blueBits = 5;
723 alphaBits = 1;
724 break;
725 case DSPF_RGB16:
726 redBits = 5;
727 greenBits = 6;
728 blueBits = 5;
729 break;
730 case DSPF_ARGB:
731 case DSPF_AiRGB:
732 alphaBits = 8;
733 case DSPF_RGB24:
734 case DSPF_RGB32:
735 redBits = 8;
736 greenBits = 8;
737 blueBits = 8;
738 break;
739 default:
740 D_WARN( "unsupported pixelformat" );
741 return false;
742 }
743
744 if (rgbFlag) {
745 accumRedBits = redBits;
746 accumGreenBits = greenBits;
747 accumBlueBits = blueBits;
748 accumAlphaBits = alphaBits;
749 depthBits = redBits + greenBits + blueBits;
750 stencilBits = alphaBits;
751 } else
752 depthBits = 8;
753
754 return _mesa_initialize_visual( visual,
755 rgbFlag, dbFlag, stereoFlag,
756 redBits, greenBits, blueBits, alphaBits,
757 indexBits, depthBits, stencilBits,
758 accumRedBits, accumGreenBits,
759 accumBlueBits, accumAlphaBits,
760 numSamples );
761 }
762
763 static bool
764 directfbgl_create_context( GLcontext *context,
765 GLframebuffer *framebuffer,
766 GLvisual *visual,
767 DFBSurfacePixelFormat format,
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 _ac_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 (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 _mesa_add_renderbuffer( framebuffer, BUFFER_FRONT_LEFT, &data->render );
890
891 _mesa_add_soft_renderbuffers( framebuffer,
892 GL_FALSE,
893 visual->haveDepthBuffer,
894 visual->haveStencilBuffer,
895 visual->haveAccumBuffer,
896 GL_FALSE,
897 GL_FALSE );
898
899 TNL_CONTEXT( context )->Driver.RunPipeline = _tnl_run_pipeline;
900
901 _mesa_enable_sw_extensions( context );
902
903 return true;
904 }
905
906 static void
907 directfbgl_destroy_context( GLcontext *context,
908 GLframebuffer *framebuffer )
909 {
910 _mesa_free_framebuffer_data( framebuffer );
911 _mesa_notifyDestroy( context );
912 _mesa_free_context_data( context );
913 }
914