2 * Copyright (C) 2004-2005 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"
41 #include "framebuffer.h"
42 #include "renderbuffer.h"
44 #include "texformat.h"
47 #include "array_cache/acache.h"
48 #include "swrast/swrast.h"
49 #include "swrast_setup/swrast_setup.h"
51 #include "tnl/t_context.h"
52 #include "tnl/t_pipeline.h"
53 #include "drivers/common/driverfuncs.h"
60 Construct( IDirectFBGL
*thiz
,
61 IDirectFBSurface
*surface
);
63 #include <direct/interface_implementation.h>
65 DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBGL
, Mesa
)
68 * private data struct of IDirectFBGL
71 int ref
; /* reference counter */
75 IDirectFBSurface
*surface
;
76 DFBSurfacePixelFormat format
;
87 GLframebuffer framebuffer
;
89 struct gl_renderbuffer render
;
93 static bool dfb_mesa_setup_visual ( GLvisual
*visual
,
94 DFBSurfacePixelFormat format
);
95 static bool dfb_mesa_create_context ( GLcontext
*context
,
96 GLframebuffer
*framebuffer
,
98 DFBSurfacePixelFormat format
,
99 IDirectFBGL_data
*data
);
100 static void dfb_mesa_destroy_context( GLcontext
*context
,
101 GLframebuffer
*framebuffer
);
105 IDirectFBGL_Destruct( IDirectFBGL
*thiz
)
107 IDirectFBGL_data
*data
= (IDirectFBGL_data
*) thiz
->priv
;
109 dfb_mesa_destroy_context( &data
->context
, &data
->framebuffer
);
111 data
->surface
->Release( data
->surface
);
113 DIRECT_DEALLOCATE_INTERFACE( thiz
);
117 IDirectFBGL_AddRef( IDirectFBGL
*thiz
)
119 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
);
127 IDirectFBGL_Release( IDirectFBGL
*thiz
)
129 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
)
131 if (--data
->ref
== 0) {
132 IDirectFBGL_Destruct( thiz
);
139 IDirectFBGL_Lock( IDirectFBGL
*thiz
)
141 IDirectFBSurface
*surface
;
146 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
);
151 surface
= data
->surface
;
152 surface
->GetSize( surface
, &width
, &height
);
154 err
= surface
->Lock( surface
, DSLF_READ
| DSLF_WRITE
,
155 (void**) &data
->video
.start
, &data
->video
.pitch
);
157 D_ERROR( "DirectFBGL/Mesa: couldn't lock surface.\n" );
160 data
->video
.end
= data
->video
.start
+ (height
-1) * data
->video
.pitch
;
162 data
->render
.Data
= data
->video
.start
;
164 if (data
->width
!= width
|| data
->height
!= height
) {
166 data
->height
= height
;
167 _mesa_ResizeBuffersMESA();
176 IDirectFBGL_Unlock( IDirectFBGL
*thiz
)
178 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
);
183 data
->surface
->Unlock( data
->surface
);
184 data
->video
.start
= NULL
;
185 data
->video
.end
= NULL
;
187 data
->locked
= false;
193 IDirectFBGL_GetAttributes( IDirectFBGL
*thiz
,
194 DFBGLAttributes
*attributes
)
198 DIRECT_INTERFACE_GET_DATA( IDirectFBGL
);
203 visual
= &data
->visual
;
205 attributes
->buffer_size
= visual
->rgbBits
? : visual
->indexBits
;
206 attributes
->depth_size
= visual
->depthBits
;
207 attributes
->stencil_size
= visual
->stencilBits
;
208 attributes
->aux_buffers
= visual
->numAuxBuffers
;
209 attributes
->red_size
= visual
->redBits
;
210 attributes
->green_size
= visual
->greenBits
;
211 attributes
->blue_size
= visual
->blueBits
;
212 attributes
->alpha_size
= visual
->alphaBits
;
213 attributes
->accum_red_size
= visual
->accumRedBits
;
214 attributes
->accum_green_size
= visual
->accumGreenBits
;
215 attributes
->accum_blue_size
= visual
->accumBlueBits
;
216 attributes
->accum_alpha_size
= visual
->accumAlphaBits
;
217 attributes
->double_buffer
= (visual
->doubleBufferMode
!= 0);
218 attributes
->stereo
= (visual
->stereoMode
!= 0);
224 /* exported symbols */
233 Construct( IDirectFBGL
*thiz
,
234 IDirectFBSurface
*surface
)
236 /* Allocate interface data. */
237 DIRECT_ALLOCATE_INTERFACE_DATA( thiz
, IDirectFBGL
);
239 /* Initialize interface data. */
241 data
->surface
= surface
;
243 surface
->AddRef( surface
);
244 surface
->GetPixelFormat( surface
, &data
->format
);
245 surface
->GetSize( surface
, &data
->width
, &data
->height
);
247 /* Configure visual. */
248 if (!dfb_mesa_setup_visual( &data
->visual
, data
->format
)) {
249 D_ERROR( "DirectFBGL/Mesa: failed to initialize visual.\n" );
250 surface
->Release( surface
);
251 return DFB_UNSUPPORTED
;
254 /* Create context. */
255 if (!dfb_mesa_create_context( &data
->context
, &data
->framebuffer
,
256 &data
->visual
, data
->format
, data
)) {
257 D_ERROR( "DirectFBGL/Mesa: failed to create context.\n" );
258 surface
->Release( surface
);
259 return DFB_UNSUPPORTED
;
262 /* Assign interface pointers. */
263 thiz
->AddRef
= IDirectFBGL_AddRef
;
264 thiz
->Release
= IDirectFBGL_Release
;
265 thiz
->Lock
= IDirectFBGL_Lock
;
266 thiz
->Unlock
= IDirectFBGL_Unlock
;
267 thiz
->GetAttributes
= IDirectFBGL_GetAttributes
;
273 /* internal functions */
275 static const GLubyte
*
276 get_string( GLcontext
*ctx
, GLenum pname
)
280 return "Claudio Ciccani";
289 update_state( GLcontext
*ctx
, GLuint new_state
)
291 _swrast_InvalidateState( ctx
, new_state
);
292 _swsetup_InvalidateState( ctx
, new_state
);
293 _ac_InvalidateState( ctx
, new_state
);
294 _tnl_InvalidateState( ctx
, new_state
);
298 get_buffer_size( GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
300 GLcontext
*ctx
= _mesa_get_current_context();
301 IDirectFBGL_data
*data
= (IDirectFBGL_data
*) ctx
->DriverCtx
;
303 *width
= (GLuint
) data
->width
;
304 *height
= (GLuint
) data
->height
;
308 set_viewport( GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
310 _mesa_ResizeBuffersMESA();
313 /* required but not used */
315 set_buffer( GLcontext
*ctx
, GLframebuffer
*buffer
, GLuint bufferBit
)
321 delete_renderbuffer( struct gl_renderbuffer
*render
)
327 renderbuffer_storage( GLcontext
*ctx
, struct gl_renderbuffer
*render
,
328 GLenum internalFormat
, GLuint width
, GLuint height
)
335 #define NAME(PREFIX) PREFIX##_RGB332
336 #define FORMAT GL_RGBA8
338 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
339 #define INIT_PIXEL_PTR(P, X, Y) \
340 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X);
341 #define INC_PIXEL_PTR(P) P += 1
342 #define STORE_PIXEL(P, X, Y, S) \
343 *P = ( (((S[RCOMP]) & 0xe0)) | (((S[GCOMP]) & 0xe0) >> 3) | ((S[BCOMP]) >> 6) )
344 #define FETCH_PIXEL(D, P) \
345 D[RCOMP] = ((*P & 0xe0) ); \
346 D[GCOMP] = ((*P & 0x1c) << 3); \
347 D[BCOMP] = ((*P & 0x03) << 6); \
350 #include "swrast/s_spantemp.h"
353 #define NAME(PREFIX) PREFIX##_ARGB1555
354 #define FORMAT GL_RGBA8
356 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
357 #define INIT_PIXEL_PTR(P, X, Y) \
358 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
359 #define INC_PIXEL_PTR(P) P += 1
360 #define STORE_PIXEL(P, X, Y, S) \
361 *P = ( (((S[RCOMP]) & 0xf8) << 7) | (((S[GCOMP]) & 0xf8) << 2) | ((S[BCOMP]) >> 3) )
362 #define FETCH_PIXEL(D, P) \
363 D[RCOMP] = ((*P & 0x7c00) >> 7); \
364 D[GCOMP] = ((*P & 0x03e0) >> 2); \
365 D[BCOMP] = ((*P & 0x001f) << 3); \
366 D[ACOMP] = ((*P & 0x8000) ? 0xff : 0)
368 #include "swrast/s_spantemp.h"
371 #define NAME(PREFIX) PREFIX##_RGB16
372 #define FORMAT GL_RGBA8
374 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
375 #define INIT_PIXEL_PTR(P, X, Y) \
376 GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2);
377 #define INC_PIXEL_PTR(P) P += 1
378 #define STORE_PIXEL(P, X, Y, S) \
379 *P = ( (((S[RCOMP]) & 0xf8) << 8) | (((S[GCOMP]) & 0xfc) << 3) | ((S[BCOMP]) >> 3) )
380 #define FETCH_PIXEL(D, P) \
381 D[RCOMP] = ((*P & 0xf800) >> 8); \
382 D[GCOMP] = ((*P & 0x07e0) >> 3); \
383 D[BCOMP] = ((*P & 0x001f) << 3); \
386 #include "swrast/s_spantemp.h"
389 #define NAME(PREFIX) PREFIX##_RGB24
390 #define FORMAT GL_RGBA8
392 IDirectFBGL_data *data = ctx->DriverCtx;
393 #define INIT_PIXEL_PTR(P, X, Y) \
394 GLubyte *P = data->video.end - (Y) * data->video.pitch + (X) * 3;
395 #define INC_PIXEL_PTR(P) P += 3
396 #define STORE_PIXEL(P, X, Y, S) \
397 P[0] = S[BCOMP]; P[1] = S[GCOMP]; P[2] = S[BCOMP]
398 #define FETCH_PIXEL(D, P) \
399 D[RCOMP] = P[2]; D[GCOMP] = P[1]; D[BCOMP] = P[0]; D[ACOMP] = 0xff
401 #include "swrast/s_spantemp.h"
404 #define NAME(PREFIX) PREFIX##_RGB32
405 #define FORMAT GL_RGBA8
407 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
408 #define INIT_PIXEL_PTR(P, X, Y) \
409 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
410 #define INC_PIXEL_PTR(P) P += 1
411 #define STORE_PIXEL(P, X, Y, S) \
412 *P = ( ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
413 #define FETCH_PIXEL(D, P) \
414 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
415 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
416 D[BCOMP] = ((*P & 0x000000ff) ); \
419 #include "swrast/s_spantemp.h"
422 #define NAME(PREFIX) PREFIX##_ARGB
423 #define FORMAT GL_RGBA8
425 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
426 #define INIT_PIXEL_PTR(P, X, Y) \
427 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
428 #define INC_PIXEL_PTR(P) P += 1
429 #define STORE_PIXEL_RGB(P, X, Y, S) \
430 *P = ( 0xff000000 | ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
431 #define STORE_PIXEL(P, X, Y, S) \
432 *P = ( ((S[ACOMP]) << 24) | ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
433 #define FETCH_PIXEL(D, P) \
434 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
435 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
436 D[BCOMP] = ((*P & 0x000000ff) ); \
437 D[ACOMP] = ((*P & 0xff000000) >> 24)
439 #include "swrast/s_spantemp.h"
442 #define NAME(PREFIX) PREFIX##_AiRGB
443 #define FORMAT GL_RGBA8
445 IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx;
446 #define INIT_PIXEL_PTR(P, X, Y) \
447 GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4);
448 #define INC_PIXEL_PTR(P) P += 1
449 #define STORE_PIXEL_RGB(P, X, Y, S) \
450 *P = ( ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
451 #define STORE_PIXEL(P, X, Y, S) \
452 *P = ( ((0xff - (S[ACOMP])) << 24) | ((S[RCOMP]) << 16) | ((S[GCOMP]) << 8) | (S[BCOMP]) )
453 #define FETCH_PIXEL(D, P) \
454 D[RCOMP] = ((*P & 0x00ff0000) >> 16); \
455 D[GCOMP] = ((*P & 0x0000ff00) >> 8); \
456 D[BCOMP] = ((*P & 0x000000ff) ); \
457 D[ACOMP] = (0xff - ((*P & 0xff000000) >> 24))
459 #include "swrast/s_spantemp.h"
463 dfb_mesa_setup_visual( GLvisual
*visual
,
464 DFBSurfacePixelFormat format
)
466 GLboolean rgbFlag
= GL_TRUE
;
467 GLboolean dbFlag
= GL_FALSE
;
468 GLboolean stereoFlag
= GL_FALSE
;
475 GLint stencilBits
= 0;
476 GLint accumRedBits
= 0;
477 GLint accumGreenBits
= 0;
478 GLint accumBlueBits
= 0;
479 GLint accumAlphaBits
= 0;
480 GLint numSamples
= 0;
482 /* FIXME: LUT8 support. */
510 D_WARN( "unsupported pixelformat" );
515 accumRedBits
= redBits
;
516 accumGreenBits
= greenBits
;
517 accumBlueBits
= blueBits
;
518 accumAlphaBits
= alphaBits
;
519 depthBits
= redBits
+ greenBits
+ blueBits
;
520 stencilBits
= alphaBits
;
524 return _mesa_initialize_visual( visual
,
525 rgbFlag
, dbFlag
, stereoFlag
,
526 redBits
, greenBits
, blueBits
, alphaBits
,
527 indexBits
, depthBits
, stencilBits
,
528 accumRedBits
, accumGreenBits
,
529 accumBlueBits
, accumAlphaBits
,
534 dfb_mesa_create_context( GLcontext
*context
,
535 GLframebuffer
*framebuffer
,
537 DFBSurfacePixelFormat format
,
538 IDirectFBGL_data
*data
)
540 struct dd_function_table functions
;
541 struct swrast_device_driver
*swdd
;
543 _mesa_initialize_framebuffer( framebuffer
, visual
);
545 _mesa_init_driver_functions( &functions
);
546 functions
.GetString
= get_string
;
547 functions
.UpdateState
= update_state
;
548 functions
.GetBufferSize
= get_buffer_size
;
549 functions
.Viewport
= set_viewport
;
551 if (!_mesa_initialize_context( context
, visual
, NULL
,
552 &functions
, (void*) data
)) {
553 D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" );
554 _mesa_free_framebuffer_data( framebuffer
);
558 _swrast_CreateContext( context
);
559 _ac_CreateContext( context
);
560 _tnl_CreateContext( context
);
561 _swsetup_CreateContext( context
);
562 _swsetup_Wakeup( context
);
564 swdd
= _swrast_GetDeviceDriverReference( context
);
565 swdd
->SetBuffer
= set_buffer
;
567 _mesa_init_renderbuffer( &data
->render
, 0 );
568 data
->render
.InternalFormat
= GL_RGBA
;
569 data
->render
._BaseFormat
= GL_RGBA
;
570 data
->render
.DataType
= GL_UNSIGNED_BYTE
;
571 data
->render
.Data
= data
->video
.start
;
572 data
->render
.Delete
= delete_renderbuffer
;
573 data
->render
.AllocStorage
= renderbuffer_storage
;
577 data
->render
.GetRow
= get_row_RGB332
;
578 data
->render
.GetValues
= get_values_RGB332
;
579 data
->render
.PutRow
= put_row_RGB332
;
580 data
->render
.PutMonoRow
= put_mono_row_RGB332
;
581 data
->render
.PutValues
= put_values_RGB332
;
582 data
->render
.PutMonoValues
= put_mono_values_RGB332
;
585 data
->render
.GetRow
= get_row_ARGB1555
;
586 data
->render
.GetValues
= get_values_ARGB1555
;
587 data
->render
.PutRow
= put_row_ARGB1555
;
588 data
->render
.PutMonoRow
= put_mono_row_ARGB1555
;
589 data
->render
.PutValues
= put_values_ARGB1555
;
590 data
->render
.PutMonoValues
= put_mono_values_ARGB1555
;
593 data
->render
.GetRow
= get_row_RGB16
;
594 data
->render
.GetValues
= get_values_RGB16
;
595 data
->render
.PutRow
= put_row_RGB16
;
596 data
->render
.PutMonoRow
= put_mono_row_RGB16
;
597 data
->render
.PutValues
= put_values_RGB16
;
598 data
->render
.PutMonoValues
= put_mono_values_RGB16
;
601 data
->render
.GetRow
= get_row_RGB24
;
602 data
->render
.GetValues
= get_values_RGB24
;
603 data
->render
.PutRow
= put_row_RGB24
;
604 data
->render
.PutMonoRow
= put_mono_row_RGB24
;
605 data
->render
.PutValues
= put_values_RGB24
;
606 data
->render
.PutMonoValues
= put_mono_values_RGB24
;
609 data
->render
.GetRow
= get_row_RGB32
;
610 data
->render
.GetValues
= get_values_RGB32
;
611 data
->render
.PutRow
= put_row_RGB32
;
612 data
->render
.PutMonoRow
= put_mono_row_RGB32
;
613 data
->render
.PutValues
= put_values_RGB32
;
614 data
->render
.PutMonoValues
= put_mono_values_RGB32
;
617 data
->render
.GetRow
= get_row_ARGB
;
618 data
->render
.GetValues
= get_values_ARGB
;
619 data
->render
.PutRow
= put_row_ARGB
;
620 data
->render
.PutMonoRow
= put_mono_row_ARGB
;
621 data
->render
.PutValues
= put_values_ARGB
;
622 data
->render
.PutMonoValues
= put_mono_values_ARGB
;
625 data
->render
.GetRow
= get_row_AiRGB
;
626 data
->render
.GetValues
= get_values_AiRGB
;
627 data
->render
.PutRow
= put_row_AiRGB
;
628 data
->render
.PutMonoRow
= put_mono_row_AiRGB
;
629 data
->render
.PutValues
= put_values_AiRGB
;
630 data
->render
.PutMonoValues
= put_mono_values_AiRGB
;
633 D_BUG( "unexpected pixelformat" );
637 _mesa_add_renderbuffer( framebuffer
, BUFFER_FRONT_LEFT
, &data
->render
);
639 _mesa_add_soft_renderbuffers( framebuffer
,
641 visual
->haveDepthBuffer
,
642 visual
->haveStencilBuffer
,
643 visual
->haveAccumBuffer
,
647 TNL_CONTEXT( context
)->Driver
.RunPipeline
= _tnl_run_pipeline
;
649 _mesa_enable_sw_extensions( context
);
651 _mesa_make_current( context
, framebuffer
, framebuffer
);
657 dfb_mesa_destroy_context( GLcontext
*context
,
658 GLframebuffer
*framebuffer
)
660 _mesa_make_current( NULL
, NULL
, NULL
);
661 _mesa_free_framebuffer_data( framebuffer
);
662 _mesa_notifyDestroy( context
);
663 _mesa_free_context_data( context
);