2 * Copyright (C) 2004 Claudio Ciccani <klan@users.sf.net>
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.
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.
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
18 * Based on glfbdev.c, written by Brian Paul.
28 #include <direct/messages.h>
29 #include <direct/interface.h>
30 #include <direct/mem.h>
36 #include "GL/directfbgl.h"
40 #include "extensions.h"
42 #include "texformat.h"
45 #include "array_cache/acache.h"
46 #include "swrast/swrast.h"
47 #include "swrast_setup/swrast_setup.h"
49 #include "tnl/t_context.h"
50 #include "tnl/t_pipeline.h"
51 #include "drivers/common/driverfuncs.h"
58 Construct( IDirectFBGL
*thiz
,
59 IDirectFBSurface
*surface
);
61 #include <direct/interface_implementation.h>
63 DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBGL
, Mesa
)
66 * private data struct of IDirectFBGL
69 int ref
; /* reference counter */
73 IDirectFBSurface
*surface
;
74 DFBSurfacePixelFormat format
;
85 GLframebuffer framebuffer
;
90 static bool dfb_mesa_setup_visual ( GLvisual
*visual
,
91 DFBSurfacePixelFormat format
);
92 static bool dfb_mesa_create_context ( GLcontext
*context
,
93 GLframebuffer
*framebuffer
,
95 DFBSurfacePixelFormat format
,
97 static void dfb_mesa_destroy_context( GLcontext
*context
,
98 GLframebuffer
*framebuffer
);
102 IDirectFBGL_Destruct( IDirectFBGL
*thiz
)
104 IDirectFBGL_data
*data
= (IDirectFBGL_data
*) thiz
->priv
;
106 dfb_mesa_destroy_context( &data
->context
, &data
->framebuffer
);
108 data
->surface
->Release( data
->surface
);
110 DIRECT_DEALLOCATE_INTERFACE( thiz
);
114 IDirectFBGL_AddRef( IDirectFBGL
*thiz
)
116 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
);
124 IDirectFBGL_Release( IDirectFBGL
*thiz
)
126 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
)
128 if (--data
->ref
== 0) {
129 IDirectFBGL_Destruct( thiz
);
136 IDirectFBGL_Lock( IDirectFBGL
*thiz
)
138 IDirectFBSurface
*surface
;
143 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
);
148 surface
= data
->surface
;
149 surface
->GetSize( surface
, &width
, &height
);
151 err
= surface
->Lock( surface
, DSLF_READ
| DSLF_WRITE
,
152 (void**) &data
->video
.start
, &data
->video
.pitch
);
154 D_ERROR( "DirectFBGL/Mesa: couldn't lock surface.\n" );
157 data
->video
.end
= data
->video
.start
+ (height
-1) * data
->video
.pitch
;
159 if (data
->width
!= width
|| data
->height
!= height
) {
161 data
->height
= height
;
162 _mesa_ResizeBuffersMESA();
171 IDirectFBGL_Unlock( IDirectFBGL
*thiz
)
173 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
);
178 data
->surface
->Unlock( data
->surface
);
179 data
->video
.start
= NULL
;
180 data
->video
.end
= NULL
;
182 data
->locked
= false;
188 IDirectFBGL_GetAttributes( IDirectFBGL
*thiz
,
189 DFBGLAttributes
*attributes
)
193 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
);
198 visual
= &data
->visual
;
200 attributes
->buffer_size
= visual
->rgbBits
? : visual
->indexBits
;
201 attributes
->depth_size
= visual
->depthBits
;
202 attributes
->stencil_size
= visual
->stencilBits
;
203 attributes
->aux_buffers
= visual
->numAuxBuffers
;
204 attributes
->red_size
= visual
->redBits
;
205 attributes
->green_size
= visual
->greenBits
;
206 attributes
->blue_size
= visual
->blueBits
;
207 attributes
->alpha_size
= visual
->alphaBits
;
208 attributes
->accum_red_size
= visual
->accumRedBits
;
209 attributes
->accum_green_size
= visual
->accumGreenBits
;
210 attributes
->accum_blue_size
= visual
->accumBlueBits
;
211 attributes
->accum_alpha_size
= visual
->accumAlphaBits
;
212 attributes
->double_buffer
= (visual
->doubleBufferMode
!= 0);
213 attributes
->stereo
= (visual
->stereoMode
!= 0);
219 /* exported symbols */
228 Construct( IDirectFBGL
*thiz
,
229 IDirectFBSurface
*surface
)
231 /* Allocate interface data. */
232 DIRECT_ALLOCATE_INTERFACE_DATA( thiz
, IDirectFBGL
);
234 /* Initialize interface data. */
236 data
->surface
= surface
;
238 surface
->AddRef( surface
);
239 surface
->GetPixelFormat( surface
, &data
->format
);
240 surface
->GetSize( surface
, &data
->width
, &data
->height
);
242 /* Configure visual. */
243 if (!dfb_mesa_setup_visual( &data
->visual
, data
->format
)) {
244 D_ERROR( "DirectFBGL/Mesa: failed to initialize visual.\n" );
245 surface
->Release( surface
);
246 return DFB_UNSUPPORTED
;
249 /* Create context. */
250 if (!dfb_mesa_create_context( &data
->context
, &data
->framebuffer
,
251 &data
->visual
, data
->format
, (void*) data
)) {
252 D_ERROR( "DirectFBGL/Mesa: failed to create context.\n" );
253 surface
->Release( surface
);
254 return DFB_UNSUPPORTED
;
257 /* Assign interface pointers. */
258 thiz
->AddRef
= IDirectFBGL_AddRef
;
259 thiz
->Release
= IDirectFBGL_Release
;
260 thiz
->Lock
= IDirectFBGL_Lock
;
261 thiz
->Unlock
= IDirectFBGL_Unlock
;
262 thiz
->GetAttributes
= IDirectFBGL_GetAttributes
;
268 /* internal functions */
270 static const GLubyte
*
271 get_string( GLcontext
*ctx
, GLenum pname
)
275 return "Claudio Ciccani";
284 update_state( GLcontext
*ctx
, GLuint new_state
)
286 _swrast_InvalidateState( ctx
, new_state
);
287 _swsetup_InvalidateState( ctx
, new_state
);
288 _ac_InvalidateState( ctx
, new_state
);
289 _tnl_InvalidateState( ctx
, new_state
);
293 get_buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
295 GLcontext
*ctx
= _mesa_get_current_context();
296 IDirectFBGL_data
*data
= (IDirectFBGL_data
*) ctx
->DriverCtx
;
298 *width
= (GLuint
) data
->width
;
299 *height
= (GLuint
) data
->height
;
303 set_viewport( GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
305 _mesa_ResizeBuffersMESA();
308 /* required but not used */
310 set_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLuint bufferBit
)
317 #define NAME(PREFIX) PREFIX##_RGB332
319 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
320 #define INIT_PIXEL_PTR(P, X, Y) \
321 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X)
322 #define INC_PIXEL_PTR(P) P += 1
323 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
324 *P = ( (((R) & 0xe0)) | (((G) & 0xe0) >> 3) | ((B) >> 6) )
325 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
326 *P = ( (((R) & 0xe0)) | (((G) & 0xe0) >> 3) | ((B) >> 6) )
327 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
328 R = ((*P & 0xe0) ); \
329 G = ((*P & 0x1c) << 3); \
330 B = ((*P & 0x03) << 6); \
333 #include "swrast/s_spantemp.h"
336 #define NAME(PREFIX) PREFIX##_ARGB1555
338 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
339 #define INIT_PIXEL_PTR(P, X, Y) \
340 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2)
341 #define INC_PIXEL_PTR(P) P += 1
342 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
343 *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
344 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
345 *P = ( (((A) & 0x80) << 8) | (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) )
346 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
347 R = ((*P & 0x7c00) >> 7); \
348 G = ((*P & 0x03e0) >> 2); \
349 B = ((*P & 0x001f) << 3); \
350 A = ((*P & 0x8000) ? 0xff : 0)
352 #include "swrast/s_spantemp.h"
355 #define NAME(PREFIX) PREFIX##_RGB16
357 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
358 #define INIT_PIXEL_PTR(P, X, Y) \
359 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2)
360 #define INC_PIXEL_PTR(P) P += 1
361 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
362 *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
363 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
364 *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) )
365 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
366 R = ((*P & 0xf800) >> 8); \
367 G = ((*P & 0x07e0) >> 3); \
368 B = ((*P & 0x001f) << 3); \
371 #include "swrast/s_spantemp.h"
374 #define NAME(PREFIX) PREFIX##_RGB24
376 IDirectFBGL_data *data = ctx->DriverCtx;
377 #define INIT_PIXEL_PTR(P, X, Y) \
378 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X) * 3
379 #define INC_PIXEL_PTR(P) P += 3
380 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
381 P[0] = B; P[1] = G; P[2] = R
382 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
383 P[0] = B; P[1] = G; P[2] = R
384 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
385 R = P[2]; G = P[1]; B = P[0]; A = CHAN_MAX
387 #include "swrast/s_spantemp.h"
390 #define NAME(PREFIX) PREFIX##_RGB32
392 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
393 #define INIT_PIXEL_PTR(P, X, Y) \
394 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4)
395 #define INC_PIXEL_PTR(P) P += 1
396 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
397 *P = ( ((R) << 16) | ((G) << 8) | (B) )
398 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
399 *P = ( ((R) << 16) | ((G) << 8) | (B) )
400 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
401 R = ((*P & 0x00ff0000) >> 16); \
402 G = ((*P & 0x0000ff00) >> 8); \
403 B = ((*P & 0x000000ff) ); \
406 #include "swrast/s_spantemp.h"
409 #define NAME(PREFIX) PREFIX##_ARGB
411 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
412 #define INIT_PIXEL_PTR(P, X, Y) \
413 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4)
414 #define INC_PIXEL_PTR(P) P += 1
415 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
416 *P = ( 0xff000000 | ((R) << 16) | ((G) << 8) | (B) )
417 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
418 *P = ( ((A) << 24) | ((R) << 16) | ((G) << 8) | (B) )
419 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
420 R = ((*P & 0x00ff0000) >> 16); \
421 G = ((*P & 0x0000ff00) >> 8); \
422 B = ((*P & 0x000000ff) ); \
423 A = ((*P & 0xff000000) >> 24)
425 #include "swrast/s_spantemp.h"
428 #define NAME(PREFIX) PREFIX##_AiRGB
430 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
431 #define INIT_PIXEL_PTR(P, X, Y) \
432 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4)
433 #define INC_PIXEL_PTR(P) P += 1
434 #define STORE_RGB_PIXEL(P, X, Y, R, G, B) \
435 *P = ( ((R) << 16) | ((G) << 8) | (B) )
436 #define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \
437 *P = ( ((0xff - (A)) << 24) | ((R) << 16) | ((G) << 8) | (B) )
438 #define FETCH_RGBA_PIXEL(R, G, B, A, P) \
439 R = ((*P & 0x00ff0000) >> 16); \
440 G = ((*P & 0x0000ff00) >> 8); \
441 B = ((*P & 0x000000ff) ); \
442 A = (0xff - ((*P & 0xff000000) >> 24))
444 #include "swrast/s_spantemp.h"
448 dfb_mesa_setup_visual( GLvisual
*visual
,
449 DFBSurfacePixelFormat format
)
451 GLboolean rgbFlag
= GL_TRUE
;
452 GLboolean dbFlag
= GL_FALSE
;
453 GLboolean stereoFlag
= GL_FALSE
;
460 GLint stencilBits
= 0;
461 GLint accumRedBits
= 0;
462 GLint accumGreenBits
= 0;
463 GLint accumBlueBits
= 0;
464 GLint accumAlphaBits
= 0;
465 GLint numSamples
= 0;
467 /* FIXME: LUT8 support. */
495 D_WARN( "unsupported pixelformat" );
500 accumRedBits
= redBits
;
501 accumGreenBits
= greenBits
;
502 accumBlueBits
= blueBits
;
503 accumAlphaBits
= alphaBits
;
504 depthBits
= redBits
+ greenBits
+ blueBits
;
505 stencilBits
= alphaBits
;
509 return _mesa_initialize_visual( visual
,
510 rgbFlag
, dbFlag
, stereoFlag
,
511 redBits
, greenBits
, blueBits
, alphaBits
,
512 indexBits
, depthBits
, stencilBits
,
513 accumRedBits
, accumGreenBits
,
514 accumBlueBits
, accumAlphaBits
,
519 dfb_mesa_create_context( GLcontext
*context
,
520 GLframebuffer
*framebuffer
,
522 DFBSurfacePixelFormat format
,
525 struct dd_function_table functions
;
526 struct swrast_device_driver
*swdd
;
528 _mesa_initialize_framebuffer( framebuffer
, visual
,
529 visual
->haveDepthBuffer
,
530 visual
->haveStencilBuffer
,
531 visual
->haveAccumBuffer
,
532 visual
->accumAlphaBits
> 0 );
534 _mesa_init_driver_functions( &functions
);
535 functions
.GetString
= get_string
;
536 functions
.UpdateState
= update_state
;
537 functions
.GetBufferSize
= get_buffer_size
;
538 functions
.Viewport
= set_viewport
;
540 if (!_mesa_initialize_context( context
, visual
, NULL
,
541 &functions
, data
)) {
542 D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" );
543 _mesa_free_framebuffer_data( framebuffer
);
547 _swrast_CreateContext( context
);
548 _ac_CreateContext( context
);
549 _tnl_CreateContext( context
);
550 _swsetup_CreateContext( context
);
551 _swsetup_Wakeup( context
);
553 swdd
= _swrast_GetDeviceDriverReference( context
);
554 swdd
->SetBuffer
= set_buffer
;
557 swdd
->WriteRGBASpan
= write_rgba_span_RGB332
;
558 swdd
->WriteRGBSpan
= write_rgb_span_RGB332
;
559 swdd
->WriteMonoRGBASpan
= write_monorgba_span_RGB332
;
560 swdd
->WriteRGBAPixels
= write_rgba_pixels_RGB332
;
561 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_RGB332
;
562 swdd
->ReadRGBASpan
= read_rgba_span_RGB332
;
563 swdd
->ReadRGBAPixels
= read_rgba_pixels_RGB332
;
566 swdd
->WriteRGBASpan
= write_rgba_span_ARGB1555
;
567 swdd
->WriteRGBSpan
= write_rgb_span_ARGB1555
;
568 swdd
->WriteMonoRGBASpan
= write_monorgba_span_ARGB1555
;
569 swdd
->WriteRGBAPixels
= write_rgba_pixels_ARGB1555
;
570 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_ARGB1555
;
571 swdd
->ReadRGBASpan
= read_rgba_span_ARGB1555
;
572 swdd
->ReadRGBAPixels
= read_rgba_pixels_ARGB1555
;
575 swdd
->WriteRGBASpan
= write_rgba_span_RGB16
;
576 swdd
->WriteRGBSpan
= write_rgb_span_RGB16
;
577 swdd
->WriteMonoRGBASpan
= write_monorgba_span_RGB16
;
578 swdd
->WriteRGBAPixels
= write_rgba_pixels_RGB16
;
579 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_RGB16
;
580 swdd
->ReadRGBASpan
= read_rgba_span_RGB16
;
581 swdd
->ReadRGBAPixels
= read_rgba_pixels_RGB16
;
584 swdd
->WriteRGBASpan
= write_rgba_span_RGB24
;
585 swdd
->WriteRGBSpan
= write_rgb_span_RGB24
;
586 swdd
->WriteMonoRGBASpan
= write_monorgba_span_RGB24
;
587 swdd
->WriteRGBAPixels
= write_rgba_pixels_RGB24
;
588 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_RGB24
;
589 swdd
->ReadRGBASpan
= read_rgba_span_RGB24
;
590 swdd
->ReadRGBAPixels
= read_rgba_pixels_RGB24
;
593 swdd
->WriteRGBASpan
= write_rgba_span_RGB32
;
594 swdd
->WriteRGBSpan
= write_rgb_span_RGB32
;
595 swdd
->WriteMonoRGBASpan
= write_monorgba_span_RGB32
;
596 swdd
->WriteRGBAPixels
= write_rgba_pixels_RGB32
;
597 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_RGB32
;
598 swdd
->ReadRGBASpan
= read_rgba_span_RGB32
;
599 swdd
->ReadRGBAPixels
= read_rgba_pixels_RGB32
;
602 swdd
->WriteRGBASpan
= write_rgba_span_ARGB
;
603 swdd
->WriteRGBSpan
= write_rgb_span_ARGB
;
604 swdd
->WriteMonoRGBASpan
= write_monorgba_span_ARGB
;
605 swdd
->WriteRGBAPixels
= write_rgba_pixels_ARGB
;
606 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_ARGB
;
607 swdd
->ReadRGBASpan
= read_rgba_span_ARGB
;
608 swdd
->ReadRGBAPixels
= read_rgba_pixels_ARGB
;
611 swdd
->WriteRGBASpan
= write_rgba_span_AiRGB
;
612 swdd
->WriteRGBSpan
= write_rgb_span_AiRGB
;
613 swdd
->WriteMonoRGBASpan
= write_monorgba_span_AiRGB
;
614 swdd
->WriteRGBAPixels
= write_rgba_pixels_AiRGB
;
615 swdd
->WriteMonoRGBAPixels
= write_monorgba_pixels_AiRGB
;
616 swdd
->ReadRGBASpan
= read_rgba_span_AiRGB
;
617 swdd
->ReadRGBAPixels
= read_rgba_pixels_AiRGB
;
620 D_BUG( "unexpected pixelformat" );
624 TNL_CONTEXT( context
)->Driver
.RunPipeline
= _tnl_run_pipeline
;
626 _mesa_enable_sw_extensions( context
);
628 _mesa_make_current( context
, framebuffer
);
634 dfb_mesa_destroy_context( GLcontext
*context
,
635 GLframebuffer
*framebuffer
)
637 _mesa_make_current( NULL
, NULL
);
638 _mesa_free_framebuffer_data( framebuffer
);
639 _mesa_notifyDestroy( context
);
640 _mesa_free_context_data( context
);