From f4092abdf94af6a99aff944d6264bc1284e8bdd4 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Mon, 10 Oct 2011 17:43:39 +0200 Subject: Imported nx-X11-3.1.0-1.tar.gz Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository --- .../extras/Mesa/src/mesa/drivers/dri/fb/Doxyfile | 232 ++++++ .../extras/Mesa/src/mesa/drivers/dri/fb/Makefile | 21 + .../extras/Mesa/src/mesa/drivers/dri/fb/fb_dri.c | 786 ++++++++++++++++++ .../extras/Mesa/src/mesa/drivers/dri/fb/fb_egl.c | 881 +++++++++++++++++++++ 4 files changed, 1920 insertions(+) create mode 100644 nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/Doxyfile create mode 100644 nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/Makefile create mode 100644 nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/fb_dri.c create mode 100644 nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/fb_egl.c (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/dri/fb') diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/Doxyfile b/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/Doxyfile new file mode 100644 index 000000000..31256db83 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/Doxyfile @@ -0,0 +1,232 @@ +# Doxyfile 1.3.2-Gideon + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = fb +PROJECT_NUMBER = $VERSION$ +OUTPUT_DIRECTORY = +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = /home/temp/Mesa/src/drv/fb +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.C \ + *.H \ + *.tlh \ + *.diff \ + *.patch \ + *.moc \ + *.xpm +RECURSIVE = yes +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = yes +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 1000 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +CGI_NAME = search.cgi +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = /usr/local/bin/ +EXT_DOC_PATHS = diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/Makefile b/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/Makefile new file mode 100644 index 000000000..12465c9f4 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/Makefile @@ -0,0 +1,21 @@ +# src/mesa/drivers/dri/fb/Makefile + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = fb_dri.so + +DRIVER_SOURCES = \ + fb_dri.c \ + fb_egl.c + +C_SOURCES = \ + $(COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +include ../Makefile.template + +symlinks: + diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/fb_dri.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/fb_dri.c new file mode 100644 index 000000000..e2ba66d2e --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/fb_dri.c @@ -0,0 +1,786 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Minimal swrast-based dri loadable driver. + * + * Todo: + * -- Use malloced (rather than framebuffer) memory for backbuffer + * -- 32bpp is hardwared -- fix + * + * NOTES: + * -- No mechanism for cliprects or resize notification -- + * assumes this is a fullscreen device. + * -- No locking -- assumes this is the only driver accessing this + * device. + * -- Doesn't (yet) make use of any acceleration or other interfaces + * provided by fb. Would be entirely happy working against any + * fullscreen interface. + * -- HOWEVER: only a small number of pixelformats are supported, and + * the mechanism for choosing between them makes some assumptions + * that may not be valid everywhere. + */ + +#include "driver.h" +#include "drm.h" +#include "utils.h" +#include "drirenderbuffer.h" + +#include "buffers.h" +#include "extensions.h" +#include "framebuffer.h" +#include "renderbuffer.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" + +void fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis); + +typedef struct { + GLcontext *glCtx; /* Mesa context */ + + struct { + __DRIcontextPrivate *context; + __DRIscreenPrivate *screen; + __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */ + } dri; + +} fbContext, *fbContextPtr; + +#define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx)) + + +static const GLubyte * +get_string(GLcontext *ctx, GLenum pname) +{ + (void) ctx; + switch (pname) { + case GL_RENDERER: + return (const GLubyte *) "Mesa dumb framebuffer"; + default: + return NULL; + } +} + + +static void +update_state( GLcontext *ctx, GLuint new_state ) +{ + /* not much to do here - pass it on */ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); +} + + +/** + * Called by ctx->Driver.GetBufferSize from in core Mesa to query the + * current framebuffer size. + */ +static void +get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) +{ + GET_CURRENT_CONTEXT(ctx); + fbContextPtr fbmesa = FB_CONTEXT(ctx); + + *width = fbmesa->dri.drawable->w; + *height = fbmesa->dri.drawable->h; +} + + +static void +viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + _mesa_ResizeBuffersMESA(); +} + + +static void +init_core_functions( struct dd_function_table *functions ) +{ + functions->GetString = get_string; + functions->UpdateState = update_state; + functions->ResizeBuffers = _mesa_resize_framebuffer; + functions->GetBufferSize = get_buffer_size; + functions->Viewport = viewport; + + functions->Clear = _swrast_Clear; /* could accelerate with blits */ +} + + +/* + * Generate code for span functions. + */ + +/* 24-bit BGR */ +#define NAME(PREFIX) PREFIX##_B8G8R8 +#define FORMAT GL_RGBA8 +#define SPAN_VARS \ + driRenderbuffer *drb = (driRenderbuffer *) rb; +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 3; +#define INC_PIXEL_PTR(P) P += 3 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[0] = VALUE[BCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[2] = VALUE[RCOMP] +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[2]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[0]; \ + DST[ACOMP] = 0xff + +#include "swrast/s_spantemp.h" + + +/* 32-bit BGRA */ +#define NAME(PREFIX) PREFIX##_B8G8R8A8 +#define FORMAT GL_RGBA8 +#define SPAN_VARS \ + driRenderbuffer *drb = (driRenderbuffer *) rb; +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 4; +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[0] = VALUE[BCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[2] = VALUE[RCOMP]; \ + DST[3] = VALUE[ACOMP] +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + DST[0] = VALUE[BCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[2] = VALUE[RCOMP]; \ + DST[3] = 0xff +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = SRC[2]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[0]; \ + DST[ACOMP] = SRC[3] + +#include "swrast/s_spantemp.h" + + +/* 16-bit BGR (XXX implement dithering someday) */ +#define NAME(PREFIX) PREFIX##_B5G6R5 +#define FORMAT GL_RGBA8 +#define SPAN_VARS \ + driRenderbuffer *drb = (driRenderbuffer *) rb; +#define INIT_PIXEL_PTR(P, X, Y) \ + GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2; +#define INC_PIXEL_PTR(P) P += 1 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) ) +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \ + DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >> 5) & 0x3) ); \ + DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \ + DST[ACOMP] = 0xff + +#include "swrast/s_spantemp.h" + + +/* 15-bit BGR (XXX implement dithering someday) */ +#define NAME(PREFIX) PREFIX##_B5G5R5 +#define FORMAT GL_RGBA8 +#define SPAN_VARS \ + driRenderbuffer *drb = (driRenderbuffer *) rb; +#define INIT_PIXEL_PTR(P, X, Y) \ + GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2; +#define INC_PIXEL_PTR(P) P += 1 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) ) +#define FETCH_PIXEL(DST, SRC) \ + DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \ + DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >> 5) & 0x7) ); \ + DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \ + DST[ACOMP] = 0xff + +#include "swrast/s_spantemp.h" + + +/* 8-bit color index */ +#define NAME(PREFIX) PREFIX##_CI8 +#define FORMAT GL_COLOR_INDEX8_EXT +#define SPAN_VARS \ + driRenderbuffer *drb = (driRenderbuffer *) rb; +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X); +#define INC_PIXEL_PTR(P) P += 1 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + *DST = VALUE[0] +#define FETCH_PIXEL(DST, SRC) \ + DST = SRC[0] + +#include "swrast/s_spantemp.h" + + + +void +fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis) +{ + ASSERT(drb->Base.InternalFormat == GL_RGBA); + if (drb->Base.InternalFormat == GL_RGBA) { + if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) { + drb->Base.GetRow = get_row_B5G6R5; + drb->Base.GetValues = get_values_B5G6R5; + drb->Base.PutRow = put_row_B5G6R5; + drb->Base.PutMonoRow = put_mono_row_B5G6R5; + drb->Base.PutRowRGB = put_row_rgb_B5G6R5; + drb->Base.PutValues = put_values_B5G6R5; + drb->Base.PutMonoValues = put_mono_values_B5G6R5; + } + else if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) { + drb->Base.GetRow = get_row_B5G5R5; + drb->Base.GetValues = get_values_B5G5R5; + drb->Base.PutRow = put_row_B5G5R5; + drb->Base.PutMonoRow = put_mono_row_B5G5R5; + drb->Base.PutRowRGB = put_row_rgb_B5G5R5; + drb->Base.PutValues = put_values_B5G5R5; + drb->Base.PutMonoValues = put_mono_values_B5G5R5; + } + else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8 + && vis->alphaBits == 8) { + drb->Base.GetRow = get_row_B8G8R8A8; + drb->Base.GetValues = get_values_B8G8R8A8; + drb->Base.PutRow = put_row_B8G8R8A8; + drb->Base.PutMonoRow = put_mono_row_B8G8R8A8; + drb->Base.PutRowRGB = put_row_rgb_B8G8R8A8; + drb->Base.PutValues = put_values_B8G8R8A8; + drb->Base.PutMonoValues = put_mono_values_B8G8R8A8; + } + else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8 + && vis->alphaBits == 0) { + drb->Base.GetRow = get_row_B8G8R8; + drb->Base.GetValues = get_values_B8G8R8; + drb->Base.PutRow = put_row_B8G8R8; + drb->Base.PutMonoRow = put_mono_row_B8G8R8; + drb->Base.PutRowRGB = put_row_rgb_B8G8R8; + drb->Base.PutValues = put_values_B8G8R8; + drb->Base.PutMonoValues = put_mono_values_B8G8R8; + } + else if (vis->indexBits == 8) { + drb->Base.GetRow = get_row_CI8; + drb->Base.GetValues = get_values_CI8; + drb->Base.PutRow = put_row_CI8; + drb->Base.PutMonoRow = put_mono_row_CI8; + drb->Base.PutValues = put_values_CI8; + drb->Base.PutMonoValues = put_mono_values_CI8; + } + } + else { + /* hardware z/stencil/etc someday */ + } +} + + + +/* Initialize the driver specific screen private data. + */ +static GLboolean +fbInitDriver( __DRIscreenPrivate *sPriv ) +{ + sPriv->private = NULL; + return GL_TRUE; +} + +static void +fbDestroyScreen( __DRIscreenPrivate *sPriv ) +{ +} + +void fbSetBuffer( GLcontext *ctx, + GLframebuffer *colorBuffer, + GLuint bufferBit ) +{ + /* NOP until SetBuffer is fully removed */ +} + +/* Create the device specific context. + */ +static GLboolean +fbCreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate) +{ + fbContextPtr fbmesa; + GLcontext *ctx, *shareCtx; + struct dd_function_table functions; + + assert(glVisual); + assert(driContextPriv); + + /* Allocate the Fb context */ + fbmesa = (fbContextPtr) _mesa_calloc( sizeof(*fbmesa) ); + if ( !fbmesa ) + return GL_FALSE; + + /* Init default driver functions then plug in our FBdev-specific functions + */ + _mesa_init_driver_functions(&functions); + init_core_functions(&functions); + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((fbContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + + ctx = fbmesa->glCtx = _mesa_create_context(glVisual, shareCtx, + &functions, (void *) fbmesa); + if (!fbmesa->glCtx) { + _mesa_free(fbmesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = fbmesa; + + /* Create module contexts */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + _swsetup_Wakeup( ctx ); + + + /* swrast init -- need to verify these tests - I just plucked the + * numbers out of the air. (KW) + */ + { + struct swrast_device_driver *swdd; + swdd = _swrast_GetDeviceDriverReference( ctx ); + swdd->SetBuffer = fbSetBuffer; + } + + /* use default TCL pipeline */ + { + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.RunPipeline = _tnl_run_pipeline; + } + + _mesa_enable_sw_extensions(ctx); + + return GL_TRUE; +} + + +static void +fbDestroyContext( __DRIcontextPrivate *driContextPriv ) +{ + GET_CURRENT_CONTEXT(ctx); + fbContextPtr fbmesa = (fbContextPtr) driContextPriv->driverPrivate; + fbContextPtr current = ctx ? FB_CONTEXT(ctx) : NULL; + + /* check if we're deleting the currently bound context */ + if (fbmesa == current) { + _mesa_make_current(NULL, NULL, NULL); + } + + /* Free fb context resources */ + if ( fbmesa ) { + _swsetup_DestroyContext( fbmesa->glCtx ); + _tnl_DestroyContext( fbmesa->glCtx ); + _ac_DestroyContext( fbmesa->glCtx ); + _swrast_DestroyContext( fbmesa->glCtx ); + + /* free the Mesa context */ + fbmesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context( fbmesa->glCtx ); + + _mesa_free( fbmesa ); + } +} + + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +static GLboolean +fbCreateBuffer( __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + struct gl_framebuffer *mesa_framebuffer; + + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + const GLboolean swDepth = mesaVis->depthBits > 0; + const GLboolean swAlpha = mesaVis->alphaBits > 0; + const GLboolean swAccum = mesaVis->accumRedBits > 0; + const GLboolean swStencil = mesaVis->stencilBits > 0; + + mesa_framebuffer = _mesa_create_framebuffer(mesaVis); + if (!mesa_framebuffer) + return 0; + + /* XXX double-check these parameters (bpp vs cpp, etc) */ + { + driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, driScrnPriv->fbBPP / 8, + driScrnPriv->fbOrigin, + driScrnPriv->fbStride); + fbSetSpanFunctions(drb, mesaVis); + drb->Base.Data = driScrnPriv->pFB; + _mesa_add_renderbuffer(mesa_framebuffer, + BUFFER_FRONT_LEFT, &drb->Base); + } + if (mesaVis->doubleBufferMode) { + /* XXX what are the correct origin/stride values? */ + driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, driScrnPriv->fbBPP /8, + driScrnPriv->fbOrigin, + driScrnPriv->fbStride); + fbSetSpanFunctions(drb, mesaVis); + drb->Base.Data = _mesa_malloc(driScrnPriv->fbStride * driScrnPriv->fbHeight); + _mesa_add_renderbuffer(mesa_framebuffer, + BUFFER_BACK_LEFT, &drb->Base); + } + + _mesa_add_soft_renderbuffers(mesa_framebuffer, + GL_FALSE, /* color */ + swDepth, + swStencil, + swAccum, + 0, + GL_FALSE /* aux */); + + driDrawPriv->driverPrivate = mesa_framebuffer; + + return 1; + } +} + + +static void +fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)driDrawPriv->driverPrivate; + + _mesa_free(mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data); + _mesa_destroy_framebuffer(mesa_framebuffer); + driDrawPriv->driverPrivate = NULL; +} + + + +/* If the backbuffer is on a videocard, this is extraordinarily slow! + */ +static void +fbSwapBuffers( __DRIdrawablePrivate *dPriv ) +{ + struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)dPriv->driverPrivate; + struct gl_renderbuffer * front_renderbuffer = mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + void *frontBuffer = front_renderbuffer->Data; + int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch; + void *backBuffer = mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data; + + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + fbContextPtr fbmesa = (fbContextPtr) dPriv->driContextPriv->driverPrivate; + GLcontext *ctx = fbmesa->glCtx; + + if (ctx->Visual.doubleBufferMode) { + int i; + int offset = 0; + char *tmp = _mesa_malloc(currentPitch); + + _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ + + ASSERT(frontBuffer); + ASSERT(backBuffer); + + for (i = 0; i < dPriv->h; i++) { + _mesa_memcpy(tmp, (char *) backBuffer + offset, + currentPitch); + _mesa_memcpy((char *) frontBuffer + offset, tmp, + currentPitch); + offset += currentPitch; + } + + _mesa_free(tmp); + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n"); + } +} + + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +static GLboolean +fbMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) +{ + if ( driContextPriv ) { + fbContextPtr newFbCtx = + (fbContextPtr) driContextPriv->driverPrivate; + + newFbCtx->dri.drawable = driDrawPriv; + + _mesa_make_current( newFbCtx->glCtx, + driDrawPriv->driverPrivate, + driReadPriv->driverPrivate); + } else { + _mesa_make_current( NULL, NULL, NULL ); + } + + return GL_TRUE; +} + + +/* Force the context `c' to be unbound from its buffer. + */ +static GLboolean +fbUnbindContext( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + +static struct __DriverAPIRec fbAPI = { + .InitDriver = fbInitDriver, + .DestroyScreen = fbDestroyScreen, + .CreateContext = fbCreateContext, + .DestroyContext = fbDestroyContext, + .CreateBuffer = fbCreateBuffer, + .DestroyBuffer = fbDestroyBuffer, + .SwapBuffers = fbSwapBuffers, + .MakeCurrent = fbMakeCurrent, + .UnbindContext = fbUnbindContext, +}; + + + +static int +__driValidateMode(const DRIDriverContext *ctx ) +{ + return 1; +} + +static int +__driInitFBDev( struct DRIDriverContextRec *ctx ) +{ + /* Note that drmOpen will try to load the kernel module, if needed. */ + /* we need a fbdev drm driver - it will only track maps */ + ctx->drmFD = drmOpen("radeon", NULL ); + if (ctx->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + ctx->shared.SAREASize = SAREA_MAX; + + if (drmAddMap( ctx->drmFD, + 0, + ctx->shared.SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &ctx->shared.hSAREA) < 0) + { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", + ctx->shared.SAREASize, ctx->shared.hSAREA); + + if (drmMap( ctx->drmFD, + ctx->shared.hSAREA, + ctx->shared.SAREASize, + (drmAddressPtr)(&ctx->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + } + memset(ctx->pSAREA, 0, ctx->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", + ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); + + /* Need to AddMap the framebuffer and mmio regions here: + */ + if (drmAddMap( ctx->drmFD, + (drm_handle_t)ctx->FBStart, + ctx->FBSize, + DRM_FRAME_BUFFER, +#ifndef _EMBEDDED + 0, +#else + DRM_READ_ONLY, +#endif + &ctx->shared.hFrameBuffer) < 0) + { + fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); + return 0; + } + + fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", + ctx->shared.hFrameBuffer); + + return 1; +} + +static void +__driHaltFBDev( struct DRIDriverContextRec *ctx ) +{ +} + +struct DRIDriverRec __driDriver = { + __driValidateMode, + __driValidateMode, + __driInitFBDev, + __driHaltFBDev +}; + +static __GLcontextModes * +fbFillInModes( unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer ) +{ + __GLcontextModes * modes; + __GLcontextModes * m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy + * enough to add support. Basically, if a context is created with an + * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping + * will never be used. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */ + }; + + u_int8_t depth_bits_array[2]; + u_int8_t stencil_bits_array[2]; + + + depth_bits_array[0] = depth_bits; + depth_bits_array[1] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; + back_buffer_factor = (have_back_buffer) ? 2 : 1; + + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if ( pixel_bits == 16 ) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_RGBA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = (*dri_interface->createContextModes)( num_modes, sizeof( __GLcontextModes ) ); + m = modes; + if ( ! driFillInModes( & m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + GLX_TRUE_COLOR ) ) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + + if ( ! driFillInModes( & m, fb_format, fb_type, + depth_bits_array, stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + GLX_DIRECT_COLOR ) ) { + fprintf( stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__ ); + return NULL; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for ( m = modes ; m != NULL ; m = m->next ) { + if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return modes; +} + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC +void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, + const __GLcontextModes * modes, + const __DRIversion * ddx_version, + const __DRIversion * dri_version, + const __DRIversion * drm_version, + const __DRIframebuffer * frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + __GLcontextModes ** driver_modes ) +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = { 4, 0, 0 }; + static const __DRIversion dri_expected = { 4, 0, 0 }; + static const __DRIversion drm_expected = { 1, 5, 0 }; + + + if ( ! driCheckDriDdxDrmVersions2( "fb", + dri_version, & dri_expected, + ddx_version, & ddx_expected, + drm_version, & drm_expected ) ) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &fbAPI); + if ( psp != NULL ) { + *driver_modes = fbFillInModes( psp->fbBPP, + (psp->fbBPP == 16) ? 16 : 24, + (psp->fbBPP == 16) ? 0 : 8, + 1); + } + + return (void *) psp; +} diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/fb_egl.c b/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/fb_egl.c new file mode 100644 index 000000000..2cea48808 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/drivers/dri/fb/fb_egl.c @@ -0,0 +1,881 @@ +/* + * Test egl driver for fb_dri.so + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "buffers.h" +#include "extensions.h" +#include "framebuffer.h" +#include "renderbuffer.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" +#include "drirenderbuffer.h" + +#include "eglconfig.h" +#include "eglcontext.h" +#include "egldisplay.h" +#include "egldriver.h" +#include "eglglobals.h" +#include "eglmode.h" +#include "eglscreen.h" +#include "eglsurface.h" + +extern void +fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis); +extern void +fbSetBuffer( GLcontext *ctx, GLframebuffer *colorBuffer, GLuint bufferBit); + +/** + * fb driver-specific driver class derived from _EGLDriver + */ +typedef struct fb_driver +{ + _EGLDriver Base; /* base class/object */ + GLuint fbStuff; +} fbDriver; + +/** + * fb display-specific driver class derived from _EGLDisplay + */ +typedef struct fb_display +{ + _EGLDisplay Base; /* base class/object */ + void *pFB; +} fbDisplay; + +/** + * fb driver-specific screen class derived from _EGLScreen + */ +typedef struct fb_screen +{ + _EGLScreen Base; + char fb[NAME_MAX]; +} fbScreen; + + +/** + * fb driver-specific surface class derived from _EGLSurface + */ +typedef struct fb_surface +{ + _EGLSurface Base; /* base class/object */ + struct gl_framebuffer *mesa_framebuffer; +} fbSurface; + + +/** + * fb driver-specific context class derived from _EGLContext + */ +typedef struct fb_context +{ + _EGLContext Base; /* base class/object */ + GLcontext *glCtx; +} fbContext; + + +static EGLBoolean +fbFillInConfigs(_EGLDisplay *disp, unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) { + _EGLConfig *configs; + _EGLConfig *c; + unsigned int i, num_configs; + unsigned int depth_buffer_factor; + unsigned int back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy + * enough to add support. Basically, if a context is created with an + * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping + * will never be used. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */ + }; + + u_int8_t depth_bits_array[2]; + u_int8_t stencil_bits_array[2]; + + depth_bits_array[0] = 0; + depth_bits_array[1] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. It will be a sw fallback, but some apps won't + * care about that. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + + depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1; + back_buffer_factor = (have_back_buffer) ? 2 : 1; + + num_configs = depth_buffer_factor * back_buffer_factor * 2; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } else { + fb_format = GL_RGBA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + configs = calloc(sizeof(*configs), num_configs); + c = configs; + if (!_eglFillInConfigs(c, fb_format, fb_type, + depth_bits_array, stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", + __func__, __LINE__); + return EGL_FALSE; + } + + /* Mark the visual as slow if there are "fake" stencil bits. + */ + for (i = 0, c = configs; i < num_configs; i++, c++) { + int stencil = GET_CONFIG_ATTRIB(c, EGL_STENCIL_SIZE); + if ((stencil != 0) && (stencil != stencil_bits)) { + SET_CONFIG_ATTRIB(c, EGL_CONFIG_CAVEAT, EGL_SLOW_CONFIG); + } + } + + for (i = 0, c = configs; i < num_configs; i++, c++) + _eglAddConfig(disp, c); + + free(configs); + + return EGL_TRUE; +} + +static EGLBoolean +fbSetupFramebuffer(fbDisplay *disp, char *fbdev) +{ + int fd; + char dev[20]; + struct fb_var_screeninfo varInfo; + struct fb_fix_screeninfo fixedInfo; + + snprintf(dev, sizeof(dev), "/dev/%s", fbdev); + + /* open the framebuffer device */ + fd = open(dev, O_RDWR); + if (fd < 0) { + fprintf(stderr, "Error opening %s: %s\n", fbdev, strerror(errno)); + return EGL_FALSE; + } + + /* get the original variable screen info */ + if (ioctl(fd, FBIOGET_VSCREENINFO, &varInfo)) { + fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n", + strerror(errno)); + return EGL_FALSE; + } + + /* Turn off hw accels (otherwise mmap of mmio region will be + * refused) + */ + if (varInfo.accel_flags) { + varInfo.accel_flags = 0; + if (ioctl(fd, FBIOPUT_VSCREENINFO, &varInfo)) { + fprintf(stderr, "error: ioctl(FBIOPUT_VSCREENINFO) failed: %s\n", + strerror(errno)); + return EGL_FALSE; + } + } + + /* Get the fixed screen info */ + if (ioctl(fd, FBIOGET_FSCREENINFO, &fixedInfo)) { + fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n", + strerror(errno)); + return EGL_FALSE; + } + + if (fixedInfo.visual == FB_VISUAL_DIRECTCOLOR) { + struct fb_cmap cmap; + unsigned short red[256], green[256], blue[256]; + int rcols = 1 << varInfo.red.length; + int gcols = 1 << varInfo.green.length; + int bcols = 1 << varInfo.blue.length; + int i; + + cmap.start = 0; + cmap.len = gcols; + cmap.red = red; + cmap.green = green; + cmap.blue = blue; + cmap.transp = NULL; + + for (i = 0; i < rcols ; i++) + red[i] = (65536/(rcols-1)) * i; + + for (i = 0; i < gcols ; i++) + green[i] = (65536/(gcols-1)) * i; + + for (i = 0; i < bcols ; i++) + blue[i] = (65536/(bcols-1)) * i; + + if (ioctl(fd, FBIOPUTCMAP, (void *) &cmap) < 0) { + fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i); + exit(1); + } + } + + /* mmap the framebuffer into our address space */ + if (!disp->pFB) + disp->pFB = (caddr_t)mmap(0, /* start */ + fixedInfo.smem_len, /* bytes */ + PROT_READ | PROT_WRITE, /* prot */ + MAP_SHARED, /* flags */ + fd, /* fd */ + 0); /* offset */ + if (disp->pFB == (caddr_t)-1) { + fprintf(stderr, "error: unable to mmap framebuffer: %s\n", + strerror(errno)); + return EGL_FALSE; + } + + return EGL_TRUE; +} + +const char *sysfs = "/sys/class/graphics"; + +static EGLBoolean +fbInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) +{ + _EGLDisplay *disp = _eglLookupDisplay(dpy); + fbDisplay *display; + fbScreen *s; + _EGLScreen *scrn; + char c; + unsigned int x, y, r; + DIR *dir; + FILE *file; + struct dirent *dirent; + char path[NAME_MAX]; + + /* Switch display structure to one with our private fields */ + display = calloc(1, sizeof(*display)); + display->Base = *disp; + _eglHashInsert(_eglGlobal.Displays, disp->Handle, display); + free(disp); + + *major = 1; + *minor = 0; + + dir = opendir(sysfs); + if (!dir) { + printf("EGL - %s framebuffer device not found.", sysfs); + return EGL_FALSE; + } + + while ((dirent = readdir(dir))) { /* assignment! */ + + if (dirent->d_name[0] != 'f') + continue; + if (dirent->d_name[1] != 'b') + continue; + + if (fbSetupFramebuffer(display, dirent->d_name) == EGL_FALSE) + continue; + + /* Create a screen */ + s = (fbScreen *) calloc(1, sizeof(fbScreen)); + if (!s) + return EGL_FALSE; + + strncpy(s->fb, dirent->d_name, NAME_MAX); + scrn = &s->Base; + _eglInitScreen(scrn); + _eglAddScreen(&display->Base, scrn); + + snprintf(path, sizeof(path), "%s/%s/modes", sysfs, s->fb); + file = fopen(path, "r"); + while (fgets(path, sizeof(path), file)) { + sscanf(path, "%c:%ux%u-%u", &c, &x, &y, &r); + _eglAddMode(scrn, x, y, r * 1000, path); + } + fclose(file); + + fbFillInConfigs(&display->Base, 32, 24, 8, 1); + + } + closedir(dir); + + drv->Initialized = EGL_TRUE; + return EGL_TRUE; +} + + +static fbDisplay * +Lookup_fbDisplay(EGLDisplay dpy) +{ + _EGLDisplay *d = _eglLookupDisplay(dpy); + return (fbDisplay *) d; +} + + +static fbScreen * +Lookup_fbScreen(EGLDisplay dpy, EGLScreenMESA screen) +{ + _EGLScreen *s = _eglLookupScreen(dpy, screen); + return (fbScreen *) s; +} + + +static fbContext * +Lookup_fbContext(EGLContext ctx) +{ + _EGLContext *c = _eglLookupContext(ctx); + return (fbContext *) c; +} + + +static fbSurface * +Lookup_fbSurface(EGLSurface surf) +{ + _EGLSurface *s = _eglLookupSurface(surf); + return (fbSurface *) s; +} + + +static EGLBoolean +fbTerminate(_EGLDriver *drv, EGLDisplay dpy) +{ + fbDisplay *display = Lookup_fbDisplay(dpy); + _eglCleanupDisplay(&display->Base); + free(display); + free(drv); + return EGL_TRUE; +} + + +static const GLubyte * +get_string(GLcontext *ctx, GLenum pname) +{ + (void) ctx; + switch (pname) { + case GL_RENDERER: + return (const GLubyte *) "Mesa dumb framebuffer"; + default: + return NULL; + } +} + + +static void +update_state( GLcontext *ctx, GLuint new_state ) +{ + /* not much to do here - pass it on */ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); +} + + +/** + * Called by ctx->Driver.GetBufferSize from in core Mesa to query the + * current framebuffer size. + */ +static void +get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) +{ + *width = buffer->Width; + *height = buffer->Height; +} + + +static void +viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + _mesa_ResizeBuffersMESA(); +} + + +static void +init_core_functions( struct dd_function_table *functions ) +{ + functions->GetString = get_string; + functions->UpdateState = update_state; + functions->ResizeBuffers = _mesa_resize_framebuffer; + functions->GetBufferSize = get_buffer_size; + functions->Viewport = viewport; + + functions->Clear = _swrast_Clear; /* could accelerate with blits */ +} + + +static EGLContext +fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) +{ + GLcontext *ctx; + _EGLConfig *conf; + fbContext *c; + _EGLDisplay *disp = _eglLookupDisplay(dpy); + struct dd_function_table functions; + GLvisual vis; + int i; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + /* no attribs defined for now */ + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext"); + return EGL_NO_CONTEXT; + } + } + + c = (fbContext *) calloc(1, sizeof(fbContext)); + if (!c) + return EGL_NO_CONTEXT; + + _eglInitContext(&c->Base); + c->Base.Display = disp; + c->Base.Config = conf; + c->Base.DrawSurface = EGL_NO_SURFACE; + c->Base.ReadSurface = EGL_NO_SURFACE; + + /* generate handle and insert into hash table */ + _eglSaveContext(&c->Base); + assert(c->Base.Handle); + + /* Init default driver functions then plug in our FBdev-specific functions + */ + _mesa_init_driver_functions(&functions); + init_core_functions(&functions); + + _eglConfigToContextModesRec(conf, &vis); + + ctx = c->glCtx = _mesa_create_context(&vis, NULL, &functions, (void *)c); + if (!c->glCtx) { + _mesa_free(c); + return GL_FALSE; + } + + /* Create module contexts */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + _swsetup_Wakeup( ctx ); + + + /* swrast init -- need to verify these tests - I just plucked the + * numbers out of the air. (KW) + */ + { + struct swrast_device_driver *swdd; + swdd = _swrast_GetDeviceDriverReference( ctx ); + swdd->SetBuffer = fbSetBuffer; + } + + /* use default TCL pipeline */ + { + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.RunPipeline = _tnl_run_pipeline; + } + + _mesa_enable_sw_extensions(ctx); + + return c->Base.Handle; +} + + +static EGLSurface +fbCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list) +{ + int i; + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + /* no attribs at this time */ + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface"); + return EGL_NO_SURFACE; + } + } + printf("eglCreateWindowSurface()\n"); + /* XXX unfinished */ + + return EGL_NO_SURFACE; +} + + +static EGLSurface +fbCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list) +{ + _EGLConfig *conf; + EGLint i; + + conf = _eglLookupConfig(drv, dpy, config); + if (!conf) { + _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface"); + return EGL_NO_SURFACE; + } + + for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) { + switch (attrib_list[i]) { + /* no attribs at this time */ + default: + _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface"); + return EGL_NO_SURFACE; + } + } + + if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) { + _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface"); + return EGL_NO_SURFACE; + } + + printf("eglCreatePixmapSurface()\n"); + return EGL_NO_SURFACE; +} + + +static EGLSurface +fbCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) +{ + fbSurface *surf; + + surf = (fbSurface *) calloc(1, sizeof(fbSurface)); + if (!surf) { + return EGL_NO_SURFACE; + } + + if (_eglInitPbufferSurface(&surf->Base, drv, dpy, config, attrib_list) == EGL_NO_SURFACE) { + free(surf); + return EGL_NO_SURFACE; + } + + /* create software-based pbuffer */ + { + GLcontext *ctx = NULL; /* this _should_ be OK */ + GLvisual vis; + _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); + assert(conf); /* bad config should be caught earlier */ + _eglConfigToContextModesRec(conf, &vis); + + surf->mesa_framebuffer = _mesa_create_framebuffer(&vis); + _mesa_add_soft_renderbuffers(surf->mesa_framebuffer, + GL_TRUE, /* color bufs */ + vis.haveDepthBuffer, + vis.haveStencilBuffer, + vis.haveAccumBuffer, + GL_FALSE, /* alpha */ + GL_FALSE /* aux */ ); + + /* set pbuffer/framebuffer size */ + _mesa_resize_framebuffer(ctx, surf->mesa_framebuffer, + surf->Base.Width, surf->Base.Height); + } + + return surf->Base.Handle; +} + + +static EGLBoolean +fbDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) +{ + fbSurface *fs = Lookup_fbSurface(surface); + _eglRemoveSurface(&fs->Base); + if (fs->Base.IsBound) { + fs->Base.DeletePending = EGL_TRUE; + } + else { + free(fs); + } + return EGL_TRUE; +} + + +static EGLBoolean +fbDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) +{ + fbContext *fc = Lookup_fbContext(context); + _eglRemoveContext(&fc->Base); + if (fc->Base.IsBound) { + fc->Base.DeletePending = EGL_TRUE; + } + else { + free(fc); + } + return EGL_TRUE; +} + + +static EGLBoolean +fbMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context) +{ + fbSurface *readSurf = Lookup_fbSurface(read); + fbSurface *drawSurf = Lookup_fbSurface(draw); + fbContext *ctx = Lookup_fbContext(context); + EGLBoolean b; + + b = _eglMakeCurrent(drv, dpy, draw, read, context); + if (!b) + return EGL_FALSE; + + if (ctx) { + _mesa_make_current( ctx->glCtx, + drawSurf->mesa_framebuffer, + readSurf->mesa_framebuffer); + } else + _mesa_make_current( NULL, NULL, NULL ); + + return EGL_TRUE; +} + + +/** + * Create a drawing surface which can be directly displayed on a screen. + */ +static EGLSurface +fbCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, + const EGLint *attrib_list) +{ + _EGLConfig *config = _eglLookupConfig(drv, dpy, cfg); + fbDisplay *display = Lookup_fbDisplay(dpy); + fbSurface *surface; + EGLSurface surf; + GLvisual vis; + GLcontext *ctx = NULL; /* this should be OK */ + int origin, bytesPerPixel; + int width, height, stride; + + surface = (fbSurface *) malloc(sizeof(*surface)); + if (!surface) { + return EGL_NO_SURFACE; + } + + /* init base class, error check, etc. */ + surf = _eglInitScreenSurface(&surface->Base, drv, dpy, cfg, attrib_list); + if (surf == EGL_NO_SURFACE) { + free(surface); + return EGL_NO_SURFACE; + } + + /* convert EGLConfig to GLvisual */ + _eglConfigToContextModesRec(config, &vis); + + /* create Mesa framebuffer */ + surface->mesa_framebuffer = _mesa_create_framebuffer(&vis); + if (!surface->mesa_framebuffer) { + free(surface); + _eglRemoveSurface(&surface->Base); + return EGL_NO_SURFACE; + } + + width = surface->Base.Width; + height = surface->Base.Height; + bytesPerPixel = vis.rgbBits / 8; + stride = width * bytesPerPixel; + origin = 0; + + /* front color renderbuffer */ + { + driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, bytesPerPixel, + origin, stride); + fbSetSpanFunctions(drb, &vis); + drb->Base.Data = display->pFB; + _mesa_add_renderbuffer(surface->mesa_framebuffer, + BUFFER_FRONT_LEFT, &drb->Base); + } + + /* back color renderbuffer */ + if (vis.doubleBufferMode) { + driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, bytesPerPixel, + origin, stride); + fbSetSpanFunctions(drb, &vis); + drb->Base.Data = _mesa_malloc(stride * height); + _mesa_add_renderbuffer(surface->mesa_framebuffer, + BUFFER_BACK_LEFT, &drb->Base); + } + + /* other renderbuffers- software based */ + _mesa_add_soft_renderbuffers(surface->mesa_framebuffer, + GL_FALSE, /* color */ + vis.haveDepthBuffer, + vis.haveStencilBuffer, + vis.haveAccumBuffer, + GL_FALSE, /* alpha */ + GL_FALSE /* aux */); + + _mesa_resize_framebuffer(ctx, surface->mesa_framebuffer, width, height); + + return surf; +} + + +/** + * Show the given surface on the named screen. + * If surface is EGL_NO_SURFACE, disable the screen's output. + */ +static EGLBoolean +fbShowSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, + EGLSurface surface, EGLModeMESA m) +{ + fbDisplay *display = Lookup_fbDisplay(dpy); + fbScreen *scrn = Lookup_fbScreen(dpy, screen); + fbSurface *surf = Lookup_fbSurface(surface); + FILE *file; + char buffer[NAME_MAX]; + _EGLMode *mode = _eglLookupMode(dpy, m); + int bits; + + if (!_eglShowSurfaceMESA(drv, dpy, screen, surface, m)) + return EGL_FALSE; + + snprintf(buffer, sizeof(buffer), "%s/%s/blank", sysfs, scrn->fb); + + file = fopen(buffer, "r+"); + if (!file) { +err: + printf("chown all fb sysfs attrib to allow write - %s\n", buffer); + return EGL_FALSE; + } + snprintf(buffer, sizeof(buffer), "%d", (m == EGL_NO_MODE_MESA ? VESA_POWERDOWN : VESA_VSYNC_SUSPEND)); + fputs(buffer, file); + fclose(file); + + if (m == EGL_NO_MODE_MESA) + return EGL_TRUE; + + snprintf(buffer, sizeof(buffer), "%s/%s/mode", sysfs, scrn->fb); + + file = fopen(buffer, "r+"); + if (!file) + goto err; + fputs(mode->Name, file); + fclose(file); + + snprintf(buffer, sizeof(buffer), "%s/%s/bits_per_pixel", sysfs, scrn->fb); + + file = fopen(buffer, "r+"); + if (!file) + goto err; + bits = GET_CONFIG_ATTRIB(surf->Base.Config, EGL_BUFFER_SIZE); + snprintf(buffer, sizeof(buffer), "%d", bits); + fputs(buffer, file); + fclose(file); + + fbSetupFramebuffer(display, scrn->fb); + + snprintf(buffer, sizeof(buffer), "%s/%s/blank", sysfs, scrn->fb); + + file = fopen(buffer, "r+"); + if (!file) + goto err; + + snprintf(buffer, sizeof(buffer), "%d", VESA_NO_BLANKING); + fputs(buffer, file); + fclose(file); + + return EGL_TRUE; +} + + +/* If the backbuffer is on a videocard, this is extraordinarily slow! + */ +static EGLBoolean +fbSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw) +{ + fbContext *context = (fbContext *)_eglGetCurrentContext(); + fbSurface *fs = Lookup_fbSurface(draw); + struct gl_renderbuffer * front_renderbuffer = fs->mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + void *frontBuffer = front_renderbuffer->Data; + int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch; + void *backBuffer = fs->mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data; + + if (!_eglSwapBuffers(drv, dpy, draw)) + return EGL_FALSE; + + if (context) { + GLcontext *ctx = context->glCtx; + + if (ctx->Visual.doubleBufferMode) { + int i; + int offset = 0; + char *tmp = _mesa_malloc(currentPitch); + + _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ + + ASSERT(frontBuffer); + ASSERT(backBuffer); + + for (i = 0; i < fs->Base.Height; i++) { + _mesa_memcpy(tmp, (char *) backBuffer + offset, + currentPitch); + _mesa_memcpy((char *) frontBuffer + offset, tmp, + currentPitch); + offset += currentPitch; + } + + _mesa_free(tmp); + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n"); + return EGL_FALSE; + } + return EGL_TRUE; +} + + +/** + * The bootstrap function. Return a new fbDriver object and + * plug in API functions. + */ +_EGLDriver * +_eglMain(_EGLDisplay *dpy) +{ + fbDriver *fb; + + fb = (fbDriver *) calloc(1, sizeof(fbDriver)); + if (!fb) { + return NULL; + } + + /* First fill in the dispatch table with defaults */ + _eglInitDriverFallbacks(&fb->Base); + + /* then plug in our fb-specific functions */ + fb->Base.Initialize = fbInitialize; + fb->Base.Terminate = fbTerminate; + fb->Base.CreateContext = fbCreateContext; + fb->Base.MakeCurrent = fbMakeCurrent; + fb->Base.CreateWindowSurface = fbCreateWindowSurface; + fb->Base.CreatePixmapSurface = fbCreatePixmapSurface; + fb->Base.CreatePbufferSurface = fbCreatePbufferSurface; + fb->Base.DestroySurface = fbDestroySurface; + fb->Base.DestroyContext = fbDestroyContext; + fb->Base.CreateScreenSurfaceMESA = fbCreateScreenSurfaceMESA; + fb->Base.ShowSurfaceMESA = fbShowSurfaceMESA; + fb->Base.SwapBuffers = fbSwapBuffers; + + /* enable supported extensions */ + fb->Base.MESA_screen_surface = EGL_TRUE; + fb->Base.MESA_copy_context = EGL_TRUE; + + return &fb->Base; +} -- cgit v1.2.3