| /* |
| * Copyright (C) 2004-2007 Claudio Ciccani <klan@directfb.org> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| * |
| * |
| * Based on glfbdev.c, written by Brian Paul. |
| * |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <unistd.h> |
| |
| #include <pthread.h> |
| |
| #include <directfb.h> |
| #include <directfb_version.h> |
| |
| #include <directfbgl.h> |
| |
| #include <direct/mem.h> |
| #include <direct/messages.h> |
| #include <direct/interface.h> |
| |
| #undef CLAMP |
| #include "glheader.h" |
| #include "buffers.h" |
| #include "context.h" |
| #include "extensions.h" |
| #include "framebuffer.h" |
| #include "renderbuffer.h" |
| #include "imports.h" |
| #include "texformat.h" |
| #include "teximage.h" |
| #include "texstore.h" |
| #include "vbo/vbo.h" |
| #include "swrast/swrast.h" |
| #include "swrast_setup/swrast_setup.h" |
| #include "tnl/tnl.h" |
| #include "tnl/t_context.h" |
| #include "tnl/t_pipeline.h" |
| #include "drivers/common/driverfuncs.h" |
| |
| |
| #define VERSION_CODE( M, m, r ) (((M) * 1000) + ((m) * 100) + ((r))) |
| #define DIRECTFB_VERSION_CODE VERSION_CODE( DIRECTFB_MAJOR_VERSION, \ |
| DIRECTFB_MINOR_VERSION, \ |
| DIRECTFB_MICRO_VERSION ) |
| |
| |
| static DFBResult |
| Probe( void *data ); |
| |
| static DFBResult |
| Construct( IDirectFBGL *thiz, |
| IDirectFBSurface *surface ); |
| |
| #include <direct/interface_implementation.h> |
| |
| DIRECT_INTERFACE_IMPLEMENTATION( IDirectFBGL, Mesa ) |
| |
| /* |
| * private data struct of IDirectFBGL |
| */ |
| typedef struct { |
| int ref; /* reference counter */ |
| |
| int locked; |
| |
| IDirectFBSurface *surface; |
| DFBSurfacePixelFormat format; |
| int width; |
| int height; |
| |
| struct { |
| GLubyte *start; |
| GLubyte *end; |
| int pitch; |
| } video; |
| |
| GLvisual visual; |
| GLframebuffer framebuffer; |
| GLcontext context; |
| struct gl_renderbuffer render; |
| } IDirectFBGL_data; |
| |
| /******************************************************************************/ |
| |
| static pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER; |
| static unsigned int global_ref = 0; |
| |
| static INLINE int directfbgl_init( void ) |
| { |
| pthread_mutexattr_t attr; |
| int ret; |
| |
| if (global_ref++) |
| return 0; |
| |
| pthread_mutexattr_init( &attr ); |
| pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK ); |
| ret = pthread_mutex_init( &global_lock, &attr ); |
| pthread_mutexattr_destroy( &attr ); |
| |
| return ret; |
| } |
| |
| static INLINE void directfbgl_finish( void ) |
| { |
| if (--global_ref == 0) |
| pthread_mutex_destroy( &global_lock ); |
| } |
| |
| #define directfbgl_lock() pthread_mutex_lock( &global_lock ) |
| #define directfbgl_unlock() pthread_mutex_unlock( &global_lock ) |
| |
| /******************************************************************************/ |
| |
| static bool directfbgl_init_visual ( GLvisual *visual, |
| DFBSurfacePixelFormat format ); |
| static bool directfbgl_create_context ( GLcontext *context, |
| GLframebuffer *framebuffer, |
| GLvisual *visual, |
| IDirectFBGL_data *data ); |
| static void directfbgl_destroy_context( GLcontext *context, |
| GLframebuffer *framebuffer ); |
| |
| /******************************************************************************/ |
| |
| |
| static void |
| IDirectFBGL_Mesa_Destruct( IDirectFBGL *thiz ) |
| { |
| IDirectFBGL_data *data = (IDirectFBGL_data*) thiz->priv; |
| |
| directfbgl_destroy_context( &data->context, &data->framebuffer ); |
| |
| if (data->surface) |
| data->surface->Release( data->surface ); |
| |
| DIRECT_DEALLOCATE_INTERFACE( thiz ); |
| |
| directfbgl_finish(); |
| } |
| |
| static DFBResult |
| IDirectFBGL_Mesa_AddRef( IDirectFBGL *thiz ) |
| { |
| DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); |
| |
| data->ref++; |
| |
| return DFB_OK; |
| } |
| |
| static DFBResult |
| IDirectFBGL_Mesa_Release( IDirectFBGL *thiz ) |
| { |
| DIRECT_INTERFACE_GET_DATA( IDirectFBGL ) |
| |
| if (--data->ref == 0) |
| IDirectFBGL_Mesa_Destruct( thiz ); |
| |
| return DFB_OK; |
| } |
| |
| static DFBResult |
| IDirectFBGL_Mesa_Lock( IDirectFBGL *thiz ) |
| { |
| IDirectFBSurface *surface; |
| int width = 0; |
| int height = 0; |
| DFBResult ret; |
| |
| DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); |
| |
| if (data->locked) { |
| data->locked++; |
| return DFB_OK; |
| } |
| |
| if (directfbgl_lock()) |
| return DFB_LOCKED; |
| |
| surface = data->surface; |
| surface->GetSize( surface, &width, &height ); |
| |
| ret = surface->Lock( surface, DSLF_READ | DSLF_WRITE, |
| (void*)&data->video.start, &data->video.pitch ); |
| if (ret) { |
| D_ERROR( "DirectFBGL/Mesa: couldn't lock surface.\n" ); |
| directfbgl_unlock(); |
| return ret; |
| } |
| data->video.end = data->video.start + (height-1) * data->video.pitch; |
| |
| data->render.Data = data->video.start; |
| |
| _mesa_make_current( &data->context, |
| &data->framebuffer, &data->framebuffer ); |
| |
| if (data->width != width || data->height != height) { |
| _mesa_resize_framebuffer( &data->context, |
| &data->framebuffer, width, height ); |
| data->width = width; |
| data->height = height; |
| } |
| |
| data->locked++; |
| |
| return DFB_OK; |
| } |
| |
| static DFBResult |
| IDirectFBGL_Mesa_Unlock( IDirectFBGL *thiz ) |
| { |
| DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); |
| |
| if (!data->locked) |
| return DFB_OK; |
| |
| if (--data->locked == 0) { |
| _mesa_make_current( NULL, NULL, NULL ); |
| |
| data->surface->Unlock( data->surface ); |
| |
| directfbgl_unlock(); |
| } |
| |
| return DFB_OK; |
| } |
| |
| static DFBResult |
| IDirectFBGL_Mesa_GetAttributes( IDirectFBGL *thiz, |
| DFBGLAttributes *attributes ) |
| { |
| DFBSurfaceCapabilities caps; |
| GLvisual *visual; |
| |
| DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); |
| |
| if (!attributes) |
| return DFB_INVARG; |
| |
| data->surface->GetCapabilities( data->surface, &caps ); |
| |
| visual = &data->visual; |
| |
| attributes->buffer_size = visual->rgbBits ? : visual->indexBits; |
| attributes->depth_size = visual->depthBits; |
| attributes->stencil_size = visual->stencilBits; |
| attributes->aux_buffers = visual->numAuxBuffers; |
| attributes->red_size = visual->redBits; |
| attributes->green_size = visual->greenBits; |
| attributes->blue_size = visual->blueBits; |
| attributes->alpha_size = visual->alphaBits; |
| attributes->accum_red_size = visual->accumRedBits; |
| attributes->accum_green_size = visual->accumGreenBits; |
| attributes->accum_blue_size = visual->accumBlueBits; |
| attributes->accum_alpha_size = visual->accumAlphaBits; |
| attributes->double_buffer = ((caps & DSCAPS_FLIPPING) != 0); |
| attributes->stereo = (visual->stereoMode != 0); |
| |
| return DFB_OK; |
| } |
| |
| #if DIRECTFBGL_INTERFACE_VERSION >= 1 |
| static DFBResult |
| IDirectFBGL_Mesa_GetProcAddress( IDirectFBGL *thiz, |
| const char *name, |
| void **ret_address ) |
| { |
| DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); |
| |
| if (!name) |
| return DFB_INVARG; |
| |
| if (!ret_address) |
| return DFB_INVARG; |
| |
| *ret_address = _glapi_get_proc_address( name ); |
| |
| return (*ret_address) ? DFB_OK : DFB_UNSUPPORTED; |
| } |
| #endif |
| |
| |
| /* exported symbols */ |
| |
| static DFBResult |
| Probe( void *data ) |
| { |
| return DFB_OK; |
| } |
| |
| static DFBResult |
| Construct( IDirectFBGL *thiz, IDirectFBSurface *surface ) |
| { |
| DFBResult ret; |
| |
| /* Initialize global resources. */ |
| if (directfbgl_init()) |
| return DFB_INIT; |
| |
| /* Allocate interface data. */ |
| DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IDirectFBGL ); |
| |
| /* Initialize interface data. */ |
| data->ref = 1; |
| |
| /* Duplicate destination surface. */ |
| ret = surface->GetSubSurface( surface, NULL, &data->surface ); |
| if (ret) { |
| IDirectFBGL_Mesa_Destruct( thiz ); |
| return ret; |
| } |
| |
| data->surface->GetPixelFormat( data->surface, &data->format ); |
| data->surface->GetSize( data->surface, &data->width, &data->height ); |
| |
| /* Configure visual. */ |
| if (!directfbgl_init_visual( &data->visual, data->format )) { |
| D_ERROR( "DirectFBGL/Mesa: failed to initialize visual.\n" ); |
| IDirectFBGL_Mesa_Destruct( thiz ); |
| return DFB_UNSUPPORTED; |
| } |
| |
| /* Create context. */ |
| if (!directfbgl_create_context( &data->context, |
| &data->framebuffer, |
| &data->visual, data )) { |
| D_ERROR( "DirectFBGL/Mesa: failed to create context.\n" ); |
| IDirectFBGL_Mesa_Destruct( thiz ); |
| return DFB_UNSUPPORTED; |
| } |
| |
| /* Assign interface pointers. */ |
| thiz->AddRef = IDirectFBGL_Mesa_AddRef; |
| thiz->Release = IDirectFBGL_Mesa_Release; |
| thiz->Lock = IDirectFBGL_Mesa_Lock; |
| thiz->Unlock = IDirectFBGL_Mesa_Unlock; |
| thiz->GetAttributes = IDirectFBGL_Mesa_GetAttributes; |
| #if DIRECTFBGL_INTERFACE_VERSION >= 1 |
| thiz->GetProcAddress = IDirectFBGL_Mesa_GetProcAddress; |
| #endif |
| |
| return DFB_OK; |
| } |
| |
| |
| /***************************** Driver functions ******************************/ |
| |
| static const GLubyte* |
| dfbGetString( GLcontext *ctx, GLenum pname ) |
| { |
| return NULL; |
| } |
| |
| static void |
| dfbUpdateState( GLcontext *ctx, GLuint new_state ) |
| { |
| _swrast_InvalidateState( ctx, new_state ); |
| _swsetup_InvalidateState( ctx, new_state ); |
| _vbo_InvalidateState( ctx, new_state ); |
| _tnl_InvalidateState( ctx, new_state ); |
| } |
| |
| static void |
| dfbGetBufferSize( GLframebuffer *buffer, GLuint *width, GLuint *height ) |
| { |
| GLcontext *ctx = _mesa_get_current_context(); |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| |
| *width = (GLuint) data->width; |
| *height = (GLuint) data->height; |
| } |
| |
| /** |
| * We only implement this function as a mechanism to check if the |
| * framebuffer size has changed (and update corresponding state). |
| */ |
| static void |
| dfbSetViewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) |
| { |
| /* Nothing to do (the surface can't be resized while it's locked). */ |
| return; |
| } |
| |
| static void |
| dfbClear( GLcontext *ctx, GLbitfield mask ) |
| { |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| |
| #define BUFFER_BIT_MASK (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT | \ |
| BUFFER_BIT_BACK_LEFT | BUFFER_BIT_BACK_RIGHT ) |
| if (mask & BUFFER_BIT_MASK && |
| ctx->Color.ColorMask[0] && |
| ctx->Color.ColorMask[1] && |
| ctx->Color.ColorMask[2] && |
| ctx->Color.ColorMask[3]) |
| { |
| DFBRegion clip; |
| GLubyte a, r, g, b; |
| |
| UNCLAMPED_FLOAT_TO_UBYTE( a, ctx->Color.ClearColor[ACOMP] ); |
| UNCLAMPED_FLOAT_TO_UBYTE( r, ctx->Color.ClearColor[RCOMP] ); |
| UNCLAMPED_FLOAT_TO_UBYTE( g, ctx->Color.ClearColor[GCOMP] ); |
| UNCLAMPED_FLOAT_TO_UBYTE( b, ctx->Color.ClearColor[BCOMP] ); |
| |
| clip.x1 = ctx->DrawBuffer->_Xmin; |
| clip.y1 = ctx->DrawBuffer->_Ymin; |
| clip.x2 = ctx->DrawBuffer->_Xmax - 1; |
| clip.y2 = ctx->DrawBuffer->_Ymax - 1; |
| data->surface->SetClip( data->surface, &clip ); |
| |
| data->surface->Unlock( data->surface ); |
| |
| data->surface->Clear( data->surface, r, g, b, a ); |
| |
| data->surface->Lock( data->surface, DSLF_READ | DSLF_WRITE, |
| (void*)&data->video.start, &data->video.pitch ); |
| data->video.end = data->video.start + (data->height-1) * data->video.pitch; |
| data->render.Data = data->video.start; |
| |
| mask &= ~BUFFER_BIT_MASK; |
| } |
| #undef BUFFER_BIT_MASK |
| |
| if (mask) |
| _swrast_Clear( ctx, mask ); |
| } |
| |
| |
| /************************ RenderBuffer functions *****************************/ |
| |
| static void |
| dfbDeleteRenderbuffer( struct gl_renderbuffer *render ) |
| { |
| return; |
| } |
| |
| static GLboolean |
| dfbRenderbufferStorage( GLcontext *ctx, struct gl_renderbuffer *render, |
| GLenum internalFormat, GLuint width, GLuint height ) |
| { |
| return GL_TRUE; |
| } |
| |
| |
| /***************************** Span functions ********************************/ |
| |
| /* RGB332 */ |
| #define NAME(PREFIX) PREFIX##_RGB332 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLubyte *P = data->video.end - (Y) * data->video.pitch + (X); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( (((S[RCOMP]) & 0xe0) ) | \ |
| (((S[GCOMP]) & 0xe0) >> 3) | \ |
| (((S[BCOMP]) ) >> 6) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0xe0) ); \ |
| D[GCOMP] = ((*P & 0x1c) << 3); \ |
| D[BCOMP] = ((*P & 0x03) << 6); \ |
| D[ACOMP] = 0xff |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* ARGB4444 */ |
| #define NAME(PREFIX) PREFIX##_ARGB4444 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL_RGB(P, X, Y, S) \ |
| *P = ( 0xf000 | \ |
| (((S[RCOMP]) & 0xf0) << 4) | \ |
| (((S[GCOMP]) & 0xf0) ) | \ |
| (((S[BCOMP]) & 0xf0) >> 4) ) |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( (((S[ACOMP]) & 0xf0) << 8) | \ |
| (((S[RCOMP]) & 0xf0) << 4) | \ |
| (((S[GCOMP]) & 0xf0) ) | \ |
| (((S[BCOMP]) & 0xf0) >> 4) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0x0f00) >> 4) | ((*P & 0x0f00) >> 8); \ |
| D[GCOMP] = ((*P & 0x00f0) ) | ((*P & 0x00f0) >> 4); \ |
| D[BCOMP] = ((*P & 0x000f) << 4) | ((*P & 0x000f) ); \ |
| D[ACOMP] = ((*P & 0xf000) >> 8) | ((*P & 0xf000) >> 12) |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* RGB444 */ |
| #define NAME(PREFIX) PREFIX##_RGB444 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( (((S[RCOMP]) & 0xf0) << 4) | \ |
| (((S[GCOMP]) & 0xf0) ) | \ |
| (((S[BCOMP]) & 0xf0) >> 4) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0x0f00) >> 4) | ((*P & 0x0f00) >> 8); \ |
| D[GCOMP] = ((*P & 0x00f0) ) | ((*P & 0x00f0) >> 4); \ |
| D[BCOMP] = ((*P & 0x000f) << 4) | ((*P & 0x000f) ); \ |
| D[ACOMP] = 0xff |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* ARGB2554 */ |
| #define NAME(PREFIX) PREFIX##_ARGB2554 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL_RGB(P, X, Y, S) \ |
| *P = ( 0xc000 | \ |
| (((S[RCOMP]) & 0xf8) << 6) | \ |
| (((S[GCOMP]) & 0xf8) << 1) | \ |
| (((S[BCOMP]) & 0xf0) >> 4) ) |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( (((S[ACOMP]) & 0xc0) << 8) | \ |
| (((S[RCOMP]) & 0xf8) << 6) | \ |
| (((S[GCOMP]) & 0xf8) << 1) | \ |
| (((S[BCOMP]) & 0xf0) >> 4) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0x3e00) >> 9); \ |
| D[GCOMP] = ((*P & 0x01f0) >> 4); \ |
| D[BCOMP] = ((*P & 0x000f) << 4); \ |
| D[ACOMP] = ((*P & 0xc000) >> 14) |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* ARGB1555 */ |
| #define NAME(PREFIX) PREFIX##_ARGB1555 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL_RGB(P, X, Y, S) \ |
| *P = ( 0x8000 | \ |
| (((S[RCOMP]) & 0xf8) << 7) | \ |
| (((S[GCOMP]) & 0xf8) << 2) | \ |
| (((S[BCOMP]) ) >> 3) ) |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( (((S[ACOMP]) & 0x80) << 16) | \ |
| (((S[RCOMP]) & 0xf8) << 7) | \ |
| (((S[GCOMP]) & 0xf8) << 2) | \ |
| (((S[BCOMP]) ) >> 3) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0x7c00) >> 7) | ((*P & 0x7c00) >> 12); \ |
| D[GCOMP] = ((*P & 0x03e0) >> 2) | ((*P & 0x03e0) >> 7); \ |
| D[BCOMP] = ((*P & 0x001f) << 3) | ((*P & 0x001f) << 2); \ |
| D[ACOMP] = ((*P & 0x8000) ? 0xff : 0) |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* RGB555 */ |
| #define NAME(PREFIX) PREFIX##_RGB555 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( (((S[RCOMP]) & 0xf8) << 7) | \ |
| (((S[GCOMP]) & 0xf8) << 2) | \ |
| (((S[BCOMP]) ) >> 3) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0x7c00) >> 7) | ((*P & 0x7c00) >> 12); \ |
| D[GCOMP] = ((*P & 0x03e0) >> 2) | ((*P & 0x03e0) >> 7); \ |
| D[BCOMP] = ((*P & 0x001f) << 3) | ((*P & 0x001f) << 2); \ |
| D[ACOMP] = 0xff |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* RGB16 */ |
| #define NAME(PREFIX) PREFIX##_RGB16 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLushort *P = (GLushort *) (data->video.end - (Y) * data->video.pitch + (X) * 2); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( (((S[RCOMP]) & 0xf8) << 8) | \ |
| (((S[GCOMP]) & 0xfc) << 3) | \ |
| (((S[BCOMP]) ) >> 3) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0xf800) >> 8) | ((*P & 0xf800) >> 13); \ |
| D[GCOMP] = ((*P & 0x07e0) >> 3) | ((*P & 0x07e0) >> 9); \ |
| D[BCOMP] = ((*P & 0x001f) << 3) | ((*P & 0x001f) >> 2); \ |
| D[ACOMP] = 0xff |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* RGB24 */ |
| #define NAME(PREFIX) PREFIX##_RGB24 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLubyte *P = data->video.end - (Y) * data->video.pitch + (X) * 3; |
| #define INC_PIXEL_PTR(P) P += 3 |
| #define STORE_PIXEL(P, X, Y, S) \ |
| P[0] = S[BCOMP]; P[1] = S[GCOMP]; P[2] = S[BCOMP] |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = P[2]; D[GCOMP] = P[1]; D[BCOMP] = P[0]; D[ACOMP] = 0xff |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* RGB32 */ |
| #define NAME(PREFIX) PREFIX##_RGB32 |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( ((S[RCOMP]) << 16) | \ |
| ((S[GCOMP]) << 8) | \ |
| ((S[BCOMP]) ) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0x00ff0000) >> 16); \ |
| D[GCOMP] = ((*P & 0x0000ff00) >> 8); \ |
| D[BCOMP] = ((*P & 0x000000ff) ); \ |
| D[ACOMP] = 0xff |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* ARGB */ |
| #define NAME(PREFIX) PREFIX##_ARGB |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL_RGB(P, X, Y, S) \ |
| *P = ( 0xff000000 | \ |
| ((S[RCOMP]) << 16) | \ |
| ((S[GCOMP]) << 8) | \ |
| ((S[BCOMP]) ) ) |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( ((S[ACOMP]) << 24) | \ |
| ((S[RCOMP]) << 16) | \ |
| ((S[GCOMP]) << 8) | \ |
| ((S[BCOMP]) ) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0x00ff0000) >> 16); \ |
| D[GCOMP] = ((*P & 0x0000ff00) >> 8); \ |
| D[BCOMP] = ((*P & 0x000000ff) ); \ |
| D[ACOMP] = ((*P & 0xff000000) >> 24) |
| |
| #include "swrast/s_spantemp.h" |
| |
| /* AiRGB */ |
| #define NAME(PREFIX) PREFIX##_AiRGB |
| #define FORMAT GL_RGBA8 |
| #define RB_TYPE GLubyte |
| #define SPAN_VARS \ |
| IDirectFBGL_data *data = (IDirectFBGL_data*) ctx->DriverCtx; |
| #define INIT_PIXEL_PTR(P, X, Y) \ |
| GLuint *P = (GLuint*) (data->video.end - (Y) * data->video.pitch + (X) * 4); |
| #define INC_PIXEL_PTR(P) P += 1 |
| #define STORE_PIXEL_RGB(P, X, Y, S) \ |
| *P = ( ((S[RCOMP]) << 16) | \ |
| ((S[GCOMP]) << 8) | \ |
| ((S[BCOMP]) ) ) |
| #define STORE_PIXEL(P, X, Y, S) \ |
| *P = ( (((S[ACOMP]) ^ 0xff) << 24) | \ |
| (((S[RCOMP]) ) << 16) | \ |
| (((S[GCOMP]) ) << 8) | \ |
| (((S[BCOMP]) ) ) ) |
| #define FETCH_PIXEL(D, P) \ |
| D[RCOMP] = ((*P & 0x00ff0000) >> 16); \ |
| D[GCOMP] = ((*P & 0x0000ff00) >> 8); \ |
| D[BCOMP] = ((*P & 0x000000ff) ); \ |
| D[ACOMP] = (((*P & 0xff000000) >> 24) ^ 0xff) |
| |
| #include "swrast/s_spantemp.h" |
| |
| |
| /*****************************************************************************/ |
| |
| static bool |
| directfbgl_init_visual( GLvisual *visual, |
| DFBSurfacePixelFormat format ) |
| { |
| GLboolean rgbFlag = GL_TRUE; |
| GLboolean dbFlag = GL_FALSE; |
| GLboolean stereoFlag = GL_FALSE; |
| GLint redBits = 0; |
| GLint blueBits = 0; |
| GLint greenBits = 0; |
| GLint alphaBits = 0; |
| GLint indexBits = 0; |
| GLint depthBits = 0; |
| GLint stencilBits = 0; |
| GLint accumRedBits = 0; |
| GLint accumGreenBits = 0; |
| GLint accumBlueBits = 0; |
| GLint accumAlphaBits = 0; |
| GLint numSamples = 0; |
| |
| /* FIXME: LUT8 support. */ |
| switch (format) { |
| case DSPF_RGB332: |
| redBits = 3; |
| greenBits = 3; |
| blueBits = 2; |
| break; |
| case DSPF_ARGB4444: |
| alphaBits = 4; |
| case DSPF_RGB444: |
| redBits = 4; |
| greenBits = 4; |
| blueBits = 4; |
| break; |
| case DSPF_ARGB2554: |
| alphaBits = 2; |
| redBits = 5; |
| greenBits = 5; |
| blueBits = 4; |
| break; |
| case DSPF_ARGB1555: |
| alphaBits = 1; |
| case DSPF_RGB555: |
| redBits = 5; |
| greenBits = 5; |
| blueBits = 5; |
| break; |
| case DSPF_RGB16: |
| redBits = 5; |
| greenBits = 6; |
| blueBits = 5; |
| break; |
| case DSPF_ARGB: |
| case DSPF_AiRGB: |
| alphaBits = 8; |
| case DSPF_RGB24: |
| case DSPF_RGB32: |
| redBits = 8; |
| greenBits = 8; |
| blueBits = 8; |
| break; |
| default: |
| D_WARN( "unsupported pixelformat" ); |
| return false; |
| } |
| |
| if (rgbFlag) { |
| accumRedBits = redBits; |
| accumGreenBits = greenBits; |
| accumBlueBits = blueBits; |
| accumAlphaBits = alphaBits; |
| depthBits = redBits + greenBits + blueBits; |
| stencilBits = alphaBits; |
| } else |
| depthBits = 8; |
| |
| return _mesa_initialize_visual( visual, |
| rgbFlag, dbFlag, stereoFlag, |
| redBits, greenBits, blueBits, alphaBits, |
| indexBits, depthBits, stencilBits, |
| accumRedBits, accumGreenBits, |
| accumBlueBits, accumAlphaBits, |
| numSamples ); |
| } |
| |
| static bool |
| directfbgl_create_context( GLcontext *context, |
| GLframebuffer *framebuffer, |
| GLvisual *visual, |
| IDirectFBGL_data *data ) |
| { |
| struct dd_function_table functions; |
| |
| _mesa_initialize_framebuffer( framebuffer, visual ); |
| |
| _mesa_init_driver_functions( &functions ); |
| functions.GetString = dfbGetString; |
| functions.UpdateState = dfbUpdateState; |
| functions.GetBufferSize = dfbGetBufferSize; |
| functions.Viewport = dfbSetViewport; |
| functions.Clear = dfbClear; |
| |
| if (!_mesa_initialize_context( context, visual, NULL, |
| &functions, (void*) data )) { |
| D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" ); |
| _mesa_free_framebuffer_data( framebuffer ); |
| return false; |
| } |
| |
| _swrast_CreateContext( context ); |
| _vbo_CreateContext( context ); |
| _tnl_CreateContext( context ); |
| _swsetup_CreateContext( context ); |
| _swsetup_Wakeup( context ); |
| |
| _mesa_init_renderbuffer( &data->render, 0 ); |
| data->render.InternalFormat = GL_RGBA; |
| data->render._BaseFormat = GL_RGBA; |
| data->render.DataType = GL_UNSIGNED_BYTE; |
| data->render.Data = data->video.start; |
| data->render.Delete = dfbDeleteRenderbuffer; |
| data->render.AllocStorage = dfbRenderbufferStorage; |
| |
| switch (data->format) { |
| case DSPF_RGB332: |
| data->render.GetRow = get_row_RGB332; |
| data->render.GetValues = get_values_RGB332; |
| data->render.PutRow = put_row_RGB332; |
| data->render.PutRowRGB = put_row_rgb_RGB332; |
| data->render.PutMonoRow = put_mono_row_RGB332; |
| data->render.PutValues = put_values_RGB332; |
| data->render.PutMonoValues = put_mono_values_RGB332; |
| break; |
| case DSPF_ARGB4444: |
| data->render.GetRow = get_row_ARGB4444; |
| data->render.GetValues = get_values_ARGB4444; |
| data->render.PutRow = put_row_ARGB4444; |
| data->render.PutRowRGB = put_row_rgb_ARGB4444; |
| data->render.PutMonoRow = put_mono_row_ARGB4444; |
| data->render.PutValues = put_values_ARGB4444; |
| data->render.PutMonoValues = put_mono_values_ARGB4444; |
| break; |
| case DSPF_RGB444: |
| data->render.GetRow = get_row_RGB444; |
| data->render.GetValues = get_values_RGB444; |
| data->render.PutRow = put_row_RGB444; |
| data->render.PutRowRGB = put_row_rgb_RGB444; |
| data->render.PutMonoRow = put_mono_row_RGB444; |
| data->render.PutValues = put_values_RGB444; |
| data->render.PutMonoValues = put_mono_values_RGB444; |
| break; |
| case DSPF_ARGB2554: |
| data->render.GetRow = get_row_ARGB2554; |
| data->render.GetValues = get_values_ARGB2554; |
| data->render.PutRow = put_row_ARGB2554; |
| data->render.PutRowRGB = put_row_rgb_ARGB2554; |
| data->render.PutMonoRow = put_mono_row_ARGB2554; |
| data->render.PutValues = put_values_ARGB2554; |
| data->render.PutMonoValues = put_mono_values_ARGB2554; |
| break; |
| case DSPF_ARGB1555: |
| data->render.GetRow = get_row_ARGB1555; |
| data->render.GetValues = get_values_ARGB1555; |
| data->render.PutRow = put_row_ARGB1555; |
| data->render.PutRowRGB = put_row_rgb_ARGB1555; |
| data->render.PutMonoRow = put_mono_row_ARGB1555; |
| data->render.PutValues = put_values_ARGB1555; |
| data->render.PutMonoValues = put_mono_values_ARGB1555; |
| break; |
| case DSPF_RGB555: |
| data->render.GetRow = get_row_RGB555; |
| data->render.GetValues = get_values_RGB555; |
| data->render.PutRow = put_row_RGB555; |
| data->render.PutRowRGB = put_row_rgb_RGB555; |
| data->render.PutMonoRow = put_mono_row_RGB555; |
| data->render.PutValues = put_values_RGB555; |
| data->render.PutMonoValues = put_mono_values_RGB555; |
| break; |
| case DSPF_RGB16: |
| data->render.GetRow = get_row_RGB16; |
| data->render.GetValues = get_values_RGB16; |
| data->render.PutRow = put_row_RGB16; |
| data->render.PutRowRGB = put_row_rgb_RGB16; |
| data->render.PutMonoRow = put_mono_row_RGB16; |
| data->render.PutValues = put_values_RGB16; |
| data->render.PutMonoValues = put_mono_values_RGB16; |
| break; |
| case DSPF_RGB24: |
| data->render.GetRow = get_row_RGB24; |
| data->render.GetValues = get_values_RGB24; |
| data->render.PutRow = put_row_RGB24; |
| data->render.PutRowRGB = put_row_rgb_RGB24; |
| data->render.PutMonoRow = put_mono_row_RGB24; |
| data->render.PutValues = put_values_RGB24; |
| data->render.PutMonoValues = put_mono_values_RGB24; |
| break; |
| case DSPF_RGB32: |
| data->render.GetRow = get_row_RGB32; |
| data->render.GetValues = get_values_RGB32; |
| data->render.PutRow = put_row_RGB32; |
| data->render.PutRowRGB = put_row_rgb_RGB32; |
| data->render.PutMonoRow = put_mono_row_RGB32; |
| data->render.PutValues = put_values_RGB32; |
| data->render.PutMonoValues = put_mono_values_RGB32; |
| break; |
| case DSPF_ARGB: |
| data->render.GetRow = get_row_ARGB; |
| data->render.GetValues = get_values_ARGB; |
| data->render.PutRow = put_row_ARGB; |
| data->render.PutRowRGB = put_row_rgb_ARGB; |
| data->render.PutMonoRow = put_mono_row_ARGB; |
| data->render.PutValues = put_values_ARGB; |
| data->render.PutMonoValues = put_mono_values_ARGB; |
| break; |
| case DSPF_AiRGB: |
| data->render.GetRow = get_row_AiRGB; |
| data->render.GetValues = get_values_AiRGB; |
| data->render.PutRow = put_row_AiRGB; |
| data->render.PutRowRGB = put_row_rgb_AiRGB; |
| data->render.PutMonoRow = put_mono_row_AiRGB; |
| data->render.PutValues = put_values_AiRGB; |
| data->render.PutMonoValues = put_mono_values_AiRGB; |
| break; |
| default: |
| D_BUG( "unexpected pixelformat" ); |
| return false; |
| } |
| |
| data->render.Width = data->width; |
| data->render.Height = data->height; |
| |
| _mesa_add_renderbuffer( framebuffer, BUFFER_FRONT_LEFT, &data->render ); |
| |
| _mesa_add_soft_renderbuffers( framebuffer, |
| GL_FALSE, |
| visual->haveDepthBuffer, |
| visual->haveStencilBuffer, |
| visual->haveAccumBuffer, |
| GL_FALSE, |
| GL_FALSE ); |
| |
| TNL_CONTEXT( context )->Driver.RunPipeline = _tnl_run_pipeline; |
| |
| _mesa_enable_sw_extensions( context ); |
| |
| return true; |
| } |
| |
| static void |
| directfbgl_destroy_context( GLcontext *context, |
| GLframebuffer *framebuffer ) |
| { |
| _swsetup_DestroyContext( context ); |
| _swrast_DestroyContext( context ); |
| _tnl_DestroyContext( context ); |
| _vbo_DestroyContext( context ); |
| //_mesa_free_framebuffer_data( framebuffer ); |
| _mesa_free_context_data( context ); |
| } |
| |