diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2005-01-03 15:35:00 +0000 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2005-01-03 15:35:00 +0000 |
commit | 81ca616e7e84768cf91234e4132df9d737b98d94 (patch) | |
tree | 7804a3d7c4de1a162bc7cd478a68e9fe88431159 | |
parent | 6563c16e381c2302ef8f76d78f8283e68aa3eb07 (diff) |
DirectFB driver (Claudio Ciccani)
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | configs/linux-directfb | 29 | ||||
-rw-r--r-- | docs/README.directfb | 28 | ||||
-rw-r--r-- | include/GL/directfbgl.h | 89 | ||||
-rw-r--r-- | src/mesa/drivers/directfb/Makefile | 53 | ||||
-rw-r--r-- | src/mesa/drivers/directfb/idirectfbgl_mesa.c | 642 |
6 files changed, 849 insertions, 1 deletions
@@ -33,7 +33,11 @@ realclean: install: @echo "Installing" - $(TOP)/bin/installmesa + $(TOP)/bin/installmesa + +# DirectFBGL module installation +linux-directfb-install: + cd src/mesa/drivers/directfb && $(MAKE) install # If there's no current configuration file $(TOP)/configs/current: @@ -78,6 +82,7 @@ linux \ linux-alpha \ linux-alpha-static \ linux-debug \ +linux-directfb \ linux-dri \ linux-dri-x86 \ linux-dri-x86-64 \ @@ -201,6 +206,8 @@ LIB_FILES = \ $(DIRECTORY)/src/mesa/drivers/beos/Makefile \ $(DIRECTORY)/src/mesa/drivers/common/*.[ch] \ $(DIRECTORY)/src/mesa/drivers/common/descrip.mms \ + $(DIRECTORY)/src/mesa/drivers/directfb/*.[ch] \ + $(DIRECTORY)/src/mesa/drivers/directfb/Makefile \ $(DIRECTORY)/src/mesa/drivers/dos/*.[chS] \ $(DIRECTORY)/src/mesa/drivers/dri/common/*.[ch] \ $(DIRECTORY)/src/mesa/drivers/fbdev/glfbdev.c \ diff --git a/configs/linux-directfb b/configs/linux-directfb new file mode 100644 index 0000000000..f09c69ddab --- /dev/null +++ b/configs/linux-directfb @@ -0,0 +1,29 @@ +# Configuration for DirectFB + +include $(TOP)/configs/default + +CONFIG_NAME = linux-directfb + +# Compiler and flags +CC = gcc +CXX = g++ + +CFLAGS = -Wall -O3 -ffast-math -fPIC -std=c99 -D_GNU_SOURCE -D_POSIX_SOURCE -D_SVID_SOURCE \ + -D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE -DPTHREADS + +CXXFLAGS = -Wall -O3 -fPIC -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE + +HAVE_X86 = $(shell uname -m | grep 'i[3-6]86' >/dev/null && echo yes) +ifeq ($(HAVE_X86), yes) + CFLAGS += -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM + CXXFLAGS += -DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM + ASM_SOURCES = $(X86_SOURCES) $(X86_API) +endif + +# Directories +SRC_DIRS = mesa glu +DRIVER_DIRS = directfb +PROGRAM_DIRS = # disabled + +# Library/program dependencies +GL_LIB_DEPS = -lm -lpthread diff --git a/docs/README.directfb b/docs/README.directfb new file mode 100644 index 0000000000..169ebe486e --- /dev/null +++ b/docs/README.directfb @@ -0,0 +1,28 @@ + + Mesa DirectFB Information + + +Requirements +============ + + To build Mesa with DirectFB (DirectFBGL) support you need: + - DirectFB at least 0.9.21 (http://directfb.org) + - pkg-config at least 0.9 (http://pkgconfig.sf.net) + + +Installation +============ + Run + + make linux-directfb + + to build Mesa and DirectFBGL module, + + make install + + to install OpenGL libraries and + + make linux-directfb-install + + to install DirectFBGL module in the proper location. + diff --git a/include/GL/directfbgl.h b/include/GL/directfbgl.h new file mode 100644 index 0000000000..984c4b1427 --- /dev/null +++ b/include/GL/directfbgl.h @@ -0,0 +1,89 @@ +/* + (c) Copyright 2001 convergence integrated media GmbH. + All rights reserved. + + Written by Denis Oliver Kropp <dok@convergence.de> and + Andreas Hundt <andi@convergence.de>. + + 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. +*/ + +#ifndef __DIRECTFBGL_H__ +#define __DIRECTFBGL_H__ + +#include <directfb.h> + +#ifdef __cplusplus +extern "C" +{ +#endif + + +typedef struct { + int buffer_size; + int depth_size; + int stencil_size; + int aux_buffers; + + int red_size; + int green_size; + int blue_size; + int alpha_size; + + int accum_red_size; + int accum_green_size; + int accum_blue_size; + int accum_alpha_size; + + DFBBoolean double_buffer; + DFBBoolean stereo; +} DFBGLAttributes; + + +DEFINE_INTERFACE( IDirectFBGL, + + /** Context handling **/ + + /* + * Acquire the hardware lock. + */ + DFBResult (*Lock) ( + IDirectFBGL *thiz + ); + + /* + * Release the lock. + */ + DFBResult (*Unlock) ( + IDirectFBGL *thiz + ); + + /* + * Query the OpenGL attributes. + */ + DFBResult (*GetAttributes) ( + IDirectFBGL *thiz, + DFBGLAttributes *attributes + ); +) + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/mesa/drivers/directfb/Makefile b/src/mesa/drivers/directfb/Makefile new file mode 100644 index 0000000000..d78662dd96 --- /dev/null +++ b/src/mesa/drivers/directfb/Makefile @@ -0,0 +1,53 @@ +# src/mesa/drivers/directfb/Makefile + +TOP = ../../../.. + +include $(TOP)/configs/current + + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/tnl \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup + +DFB_CFLAGS = $(shell pkg-config --cflags directfb) +DFB_MODULEDIR = $(shell pkg-config --variable=moduledir directfb-internal) + +DIRECTFBGL_MESA_SOURCES = ../common/driverfuncs.c idirectfbgl_mesa.c + +DIRECTFBGL_MESA_OBJECTS = $(DIRECTFBGL_MESA_SOURCES:.c=.o) + +DIRECTFBGL_MESA = libidirectfbgl_mesa.so + +.c.o: + $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DFB_CFLAGS) $< -o $@ + + +default: directfbgl_mesa + +# Mesa DirectFBGL module +directfbgl_mesa: $(DIRECTFBGL_MESA_OBJECTS) + $(CC) -shared $(CFLAGS) $(DIRECTFBGL_MESA_OBJECTS) -o $(DIRECTFBGL_MESA) \ + -Wl,-soname -Wl,$(DIRECTFBGL_MESA) -L$(TOP)/lib -lGL -lm + + +install: + @if test -d $(DFB_MODULEDIR); then \ + echo "Installing DirectFBGL module."; \ + else \ + echo "*** Failed to determine DirectFB module's directory."; \ + echo "*** Installation aborted."; \ + exit 1; \ + fi; + install -m 0755 $(DIRECTFBGL_MESA) $(DFB_MODULEDIR)/interfaces/IDirectFBGL/ + + +clean: + rm -f *.o *.so + diff --git a/src/mesa/drivers/directfb/idirectfbgl_mesa.c b/src/mesa/drivers/directfb/idirectfbgl_mesa.c new file mode 100644 index 0000000000..c438b86421 --- /dev/null +++ b/src/mesa/drivers/directfb/idirectfbgl_mesa.c @@ -0,0 +1,642 @@ +/* + * Copyright (C) 2004 Claudio Ciccani <klan@users.sf.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; 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 <directfb.h> + +#include <direct/messages.h> +#include <direct/interface.h> +#include <direct/mem.h> + +#ifdef CLAMP +# undef CLAMP +#endif + +#include "GL/directfbgl.h" +#include "glheader.h" +#include "buffers.h" +#include "context.h" +#include "extensions.h" +#include "imports.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" +#include "array_cache/acache.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" + + +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 */ + + bool locked; + + IDirectFBSurface *surface; + DFBSurfacePixelFormat format; + int width; + int height; + + struct { + __u8 *start; + __u8 *end; + int pitch; + } video; + + GLvisual visual; + GLframebuffer framebuffer; + GLcontext context; +} IDirectFBGL_data; + + +static bool dfb_mesa_setup_visual ( GLvisual *visual, + DFBSurfacePixelFormat format ); +static bool dfb_mesa_create_context ( GLcontext *context, + GLframebuffer *framebuffer, + GLvisual *visual, + DFBSurfacePixelFormat format, + void *data ); +static void dfb_mesa_destroy_context( GLcontext *context, + GLframebuffer *framebuffer ); + + +static void +IDirectFBGL_Destruct( IDirectFBGL *thiz ) +{ + IDirectFBGL_data *data = (IDirectFBGL_data*) thiz->priv; + + dfb_mesa_destroy_context( &data->context, &data->framebuffer ); + + data->surface->Release( data->surface ); + + DIRECT_DEALLOCATE_INTERFACE( thiz ); +} + +static DFBResult +IDirectFBGL_AddRef( IDirectFBGL *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); + + data->ref++; + + return DFB_OK; +} + +static DFBResult +IDirectFBGL_Release( IDirectFBGL *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBGL ) + + if (--data->ref == 0) { + IDirectFBGL_Destruct( thiz ); + } + + return DFB_OK; +} + +static DFBResult +IDirectFBGL_Lock( IDirectFBGL *thiz ) +{ + IDirectFBSurface *surface; + int width = 0; + int height = 0; + DFBResult err; + + DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); + + if (data->locked) + return DFB_LOCKED; + + surface = data->surface; + surface->GetSize( surface, &width, &height ); + + err = surface->Lock( surface, DSLF_READ | DSLF_WRITE, + (void**) &data->video.start, &data->video.pitch ); + if (err != DFB_OK) { + D_ERROR( "DirectFBGL/Mesa: couldn't lock surface.\n" ); + return err; + } + data->video.end = data->video.start + (height-1) * data->video.pitch; + + if (data->width != width || data->height != height) { + data->width = width; + data->height = height; + _mesa_ResizeBuffersMESA(); + } + + data->locked = true; + + return DFB_OK; +} + +static DFBResult +IDirectFBGL_Unlock( IDirectFBGL *thiz ) +{ + DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); + + if (!data->locked) + return DFB_OK; + + data->surface->Unlock( data->surface ); + data->video.start = NULL; + data->video.end = NULL; + + data->locked = false; + + return DFB_OK; +} + +static DFBResult +IDirectFBGL_GetAttributes( IDirectFBGL *thiz, + DFBGLAttributes *attributes ) +{ + GLvisual *visual; + + DIRECT_INTERFACE_GET_DATA( IDirectFBGL ); + + if (!attributes) + return DFB_INVARG; + + 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 = (visual->doubleBufferMode != 0); + attributes->stereo = (visual->stereoMode != 0); + + return DFB_OK; +} + + +/* exported symbols */ + +static DFBResult +Probe( void *data ) +{ + return DFB_OK; +} + +static DFBResult +Construct( IDirectFBGL *thiz, + IDirectFBSurface *surface ) +{ + /* Allocate interface data. */ + DIRECT_ALLOCATE_INTERFACE_DATA( thiz, IDirectFBGL ); + + /* Initialize interface data. */ + data->ref = 1; + data->surface = surface; + + surface->AddRef( surface ); + surface->GetPixelFormat( surface, &data->format ); + surface->GetSize( surface, &data->width, &data->height ); + + /* Configure visual. */ + if (!dfb_mesa_setup_visual( &data->visual, data->format )) { + D_ERROR( "DirectFBGL/Mesa: failed to initialize visual.\n" ); + surface->Release( surface ); + return DFB_UNSUPPORTED; + } + + /* Create context. */ + if (!dfb_mesa_create_context( &data->context, &data->framebuffer, + &data->visual, data->format, (void*) data )) { + D_ERROR( "DirectFBGL/Mesa: failed to create context.\n" ); + surface->Release( surface ); + return DFB_UNSUPPORTED; + } + + /* Assign interface pointers. */ + thiz->AddRef = IDirectFBGL_AddRef; + thiz->Release = IDirectFBGL_Release; + thiz->Lock = IDirectFBGL_Lock; + thiz->Unlock = IDirectFBGL_Unlock; + thiz->GetAttributes = IDirectFBGL_GetAttributes; + + return DFB_OK; +} + + +/* internal functions */ + +static const GLubyte* +get_string( GLcontext *ctx, GLenum pname ) +{ + switch (pname) { + case GL_VENDOR: + return "Claudio Ciccani"; + case GL_VERSION: + return "1.0"; + default: + return NULL; + } +} + +static void +update_state( GLcontext *ctx, GLuint new_state ) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); +} + +static void +get_buffer_size( 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; +} + +static void +set_viewport( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) +{ + _mesa_ResizeBuffersMESA(); +} + +/* required but not used */ +static void +set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit ) +{ + return; +} + + +/* RGB332 */ +#define NAME(PREFIX) PREFIX##_RGB332 +#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_RGB_PIXEL(P, X, Y, R, G, B) \ + *P = ( (((R) & 0xe0)) | (((G) & 0xe0) >> 3) | ((B) >> 6) ) +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + *P = ( (((R) & 0xe0)) | (((G) & 0xe0) >> 3) | ((B) >> 6) ) +#define FETCH_RGBA_PIXEL(R, G, B, A, P) \ + R = ((*P & 0xe0) ); \ + G = ((*P & 0x1c) << 3); \ + B = ((*P & 0x03) << 6); \ + A = CHAN_MAX + +#include "swrast/s_spantemp.h" + +/* ARGB1555 */ +#define NAME(PREFIX) PREFIX##_ARGB1555 +#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_RGB_PIXEL(P, X, Y, R, G, B) \ + *P = ( (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) ) +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + *P = ( (((A) & 0x80) << 8) | (((R) & 0xf8) << 7) | (((G) & 0xf8) << 2) | ((B) >> 3) ) +#define FETCH_RGBA_PIXEL(R, G, B, A, P) \ + R = ((*P & 0x7c00) >> 7); \ + G = ((*P & 0x03e0) >> 2); \ + B = ((*P & 0x001f) << 3); \ + A = ((*P & 0x8000) ? 0xff : 0) + +#include "swrast/s_spantemp.h" + +/* RGB16 */ +#define NAME(PREFIX) PREFIX##_RGB16 +#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_RGB_PIXEL(P, X, Y, R, G, B) \ + *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) ) +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + *P = ( (((R) & 0xf8) << 8) | (((G) & 0xfc) << 3) | ((B) >> 3) ) +#define FETCH_RGBA_PIXEL(R, G, B, A, P) \ + R = ((*P & 0xf800) >> 8); \ + G = ((*P & 0x07e0) >> 3); \ + B = ((*P & 0x001f) << 3); \ + A = CHAN_MAX + +#include "swrast/s_spantemp.h" + +/* RGB24 */ +#define NAME(PREFIX) PREFIX##_RGB24 +#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_RGB_PIXEL(P, X, Y, R, G, B) \ + P[0] = B; P[1] = G; P[2] = R +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + P[0] = B; P[1] = G; P[2] = R +#define FETCH_RGBA_PIXEL(R, G, B, A, P) \ + R = P[2]; G = P[1]; B = P[0]; A = CHAN_MAX + +#include "swrast/s_spantemp.h" + +/* RGB32 */ +#define NAME(PREFIX) PREFIX##_RGB32 +#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_RGB_PIXEL(P, X, Y, R, G, B) \ + *P = ( ((R) << 16) | ((G) << 8) | (B) ) +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + *P = ( ((R) << 16) | ((G) << 8) | (B) ) +#define FETCH_RGBA_PIXEL(R, G, B, A, P) \ + R = ((*P & 0x00ff0000) >> 16); \ + G = ((*P & 0x0000ff00) >> 8); \ + B = ((*P & 0x000000ff) ); \ + A = CHAN_MAX + +#include "swrast/s_spantemp.h" + +/* ARGB */ +#define NAME(PREFIX) PREFIX##_ARGB +#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_RGB_PIXEL(P, X, Y, R, G, B) \ + *P = ( 0xff000000 | ((R) << 16) | ((G) << 8) | (B) ) +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + *P = ( ((A) << 24) | ((R) << 16) | ((G) << 8) | (B) ) +#define FETCH_RGBA_PIXEL(R, G, B, A, P) \ + R = ((*P & 0x00ff0000) >> 16); \ + G = ((*P & 0x0000ff00) >> 8); \ + B = ((*P & 0x000000ff) ); \ + A = ((*P & 0xff000000) >> 24) + +#include "swrast/s_spantemp.h" + +/* AiRGB */ +#define NAME(PREFIX) PREFIX##_AiRGB +#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_RGB_PIXEL(P, X, Y, R, G, B) \ + *P = ( ((R) << 16) | ((G) << 8) | (B) ) +#define STORE_RGBA_PIXEL(P, X, Y, R, G, B, A) \ + *P = ( ((0xff - (A)) << 24) | ((R) << 16) | ((G) << 8) | (B) ) +#define FETCH_RGBA_PIXEL(R, G, B, A, P) \ + R = ((*P & 0x00ff0000) >> 16); \ + G = ((*P & 0x0000ff00) >> 8); \ + B = ((*P & 0x000000ff) ); \ + A = (0xff - ((*P & 0xff000000) >> 24)) + +#include "swrast/s_spantemp.h" + + +static bool +dfb_mesa_setup_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_ARGB1555: + redBits = 5; + greenBits = 5; + blueBits = 5; + alphaBits = 1; + 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 +dfb_mesa_create_context( GLcontext *context, + GLframebuffer *framebuffer, + GLvisual *visual, + DFBSurfacePixelFormat format, + void *data ) +{ + struct dd_function_table functions; + struct swrast_device_driver *swdd; + + _mesa_initialize_framebuffer( framebuffer, visual, + visual->haveDepthBuffer, + visual->haveStencilBuffer, + visual->haveAccumBuffer, + visual->accumAlphaBits > 0 ); + + _mesa_init_driver_functions( &functions ); + functions.GetString = get_string; + functions.UpdateState = update_state; + functions.GetBufferSize = get_buffer_size; + functions.Viewport = set_viewport; + + if (!_mesa_initialize_context( context, visual, NULL, + &functions, data )) { + D_DEBUG( "DirectFBGL/Mesa: _mesa_initialize_context() failed.\n" ); + _mesa_free_framebuffer_data( framebuffer ); + return false; + } + + _swrast_CreateContext( context ); + _ac_CreateContext( context ); + _tnl_CreateContext( context ); + _swsetup_CreateContext( context ); + _swsetup_Wakeup( context ); + + swdd = _swrast_GetDeviceDriverReference( context ); + swdd->SetBuffer = set_buffer; + switch (format) { + case DSPF_RGB332: + swdd->WriteRGBASpan = write_rgba_span_RGB332; + swdd->WriteRGBSpan = write_rgb_span_RGB332; + swdd->WriteMonoRGBASpan = write_monorgba_span_RGB332; + swdd->WriteRGBAPixels = write_rgba_pixels_RGB332; + swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB332; + swdd->ReadRGBASpan = read_rgba_span_RGB332; + swdd->ReadRGBAPixels = read_rgba_pixels_RGB332; + break; + case DSPF_ARGB1555: + swdd->WriteRGBASpan = write_rgba_span_ARGB1555; + swdd->WriteRGBSpan = write_rgb_span_ARGB1555; + swdd->WriteMonoRGBASpan = write_monorgba_span_ARGB1555; + swdd->WriteRGBAPixels = write_rgba_pixels_ARGB1555; + swdd->WriteMonoRGBAPixels = write_monorgba_pixels_ARGB1555; + swdd->ReadRGBASpan = read_rgba_span_ARGB1555; + swdd->ReadRGBAPixels = read_rgba_pixels_ARGB1555; + break; + case DSPF_RGB16: + swdd->WriteRGBASpan = write_rgba_span_RGB16; + swdd->WriteRGBSpan = write_rgb_span_RGB16; + swdd->WriteMonoRGBASpan = write_monorgba_span_RGB16; + swdd->WriteRGBAPixels = write_rgba_pixels_RGB16; + swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB16; + swdd->ReadRGBASpan = read_rgba_span_RGB16; + swdd->ReadRGBAPixels = read_rgba_pixels_RGB16; + break; + case DSPF_RGB24: + swdd->WriteRGBASpan = write_rgba_span_RGB24; + swdd->WriteRGBSpan = write_rgb_span_RGB24; + swdd->WriteMonoRGBASpan = write_monorgba_span_RGB24; + swdd->WriteRGBAPixels = write_rgba_pixels_RGB24; + swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB24; + swdd->ReadRGBASpan = read_rgba_span_RGB24; + swdd->ReadRGBAPixels = read_rgba_pixels_RGB24; + break; + case DSPF_RGB32: + swdd->WriteRGBASpan = write_rgba_span_RGB32; + swdd->WriteRGBSpan = write_rgb_span_RGB32; + swdd->WriteMonoRGBASpan = write_monorgba_span_RGB32; + swdd->WriteRGBAPixels = write_rgba_pixels_RGB32; + swdd->WriteMonoRGBAPixels = write_monorgba_pixels_RGB32; + swdd->ReadRGBASpan = read_rgba_span_RGB32; + swdd->ReadRGBAPixels = read_rgba_pixels_RGB32; + break; + case DSPF_ARGB: + swdd->WriteRGBASpan = write_rgba_span_ARGB; + swdd->WriteRGBSpan = write_rgb_span_ARGB; + swdd->WriteMonoRGBASpan = write_monorgba_span_ARGB; + swdd->WriteRGBAPixels = write_rgba_pixels_ARGB; + swdd->WriteMonoRGBAPixels = write_monorgba_pixels_ARGB; + swdd->ReadRGBASpan = read_rgba_span_ARGB; + swdd->ReadRGBAPixels = read_rgba_pixels_ARGB; + break; + case DSPF_AiRGB: + swdd->WriteRGBASpan = write_rgba_span_AiRGB; + swdd->WriteRGBSpan = write_rgb_span_AiRGB; + swdd->WriteMonoRGBASpan = write_monorgba_span_AiRGB; + swdd->WriteRGBAPixels = write_rgba_pixels_AiRGB; + swdd->WriteMonoRGBAPixels = write_monorgba_pixels_AiRGB; + swdd->ReadRGBASpan = read_rgba_span_AiRGB; + swdd->ReadRGBAPixels = read_rgba_pixels_AiRGB; + break; + default: + D_BUG( "unexpected pixelformat" ); + return false; + } + + TNL_CONTEXT( context )->Driver.RunPipeline = _tnl_run_pipeline; + + _mesa_enable_sw_extensions( context ); + + _mesa_make_current( context, framebuffer ); + + return true; +} + +static void +dfb_mesa_destroy_context( GLcontext *context, + GLframebuffer *framebuffer ) +{ + _mesa_make_current( NULL, NULL ); + _mesa_free_framebuffer_data( framebuffer ); + _mesa_notifyDestroy( context ); + _mesa_free_context_data( context ); +} + |