aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/Mesa/src/mesa/drivers/fbdev/glfbdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/drivers/fbdev/glfbdev.c')
-rw-r--r--nx-X11/extras/Mesa/src/mesa/drivers/fbdev/glfbdev.c861
1 files changed, 861 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/drivers/fbdev/glfbdev.c b/nx-X11/extras/Mesa/src/mesa/drivers/fbdev/glfbdev.c
new file mode 100644
index 000000000..c8d9375b6
--- /dev/null
+++ b/nx-X11/extras/Mesa/src/mesa/drivers/fbdev/glfbdev.c
@@ -0,0 +1,861 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 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.
+ */
+
+
+/*
+ * OpenGL (Mesa) interface for fbdev.
+ * For info about fbdev:
+ * http://www.tldp.org/HOWTO/Framebuffer-HOWTO.html
+ *
+ * known VGA modes
+ * Colours 640x400 640x480 800x600 1024x768 1152x864 1280x1024 1600x1200
+ * --------+--------------------------------------------------------------
+ * 4 bits | ? ? 0x302 ? ? ? ?
+ * 8 bits | 0x300 0x301 0x303 0x305 0x161 0x307 0x31C
+ * 15 bits | ? 0x310 0x313 0x316 0x162 0x319 0x31D
+ * 16 bits | ? 0x311 0x314 0x317 0x163 0x31A 0x31E
+ * 24 bits | ? 0x312 0x315 0x318 ? 0x31B 0x31F
+ * 32 bits | ? ? ? ? 0x164 ?
+ */
+#ifdef USE_GLFBDEV_DRIVER
+
+#include "glheader.h"
+#include <linux/fb.h>
+#include "GL/glfbdev.h"
+#include "buffers.h"
+#include "context.h"
+#include "extensions.h"
+#include "fbobject.h"
+#include "framebuffer.h"
+#include "imports.h"
+#include "renderbuffer.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"
+
+
+#define PF_B8G8R8 1
+#define PF_B8G8R8A8 2
+#define PF_B5G6R5 3
+#define PF_B5G5R5 4
+#define PF_CI8 5
+
+
+/*
+ * Derived from Mesa's GLvisual class.
+ */
+struct GLFBDevVisualRec {
+ GLvisual glvisual; /* base class */
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+ int pixelFormat;
+};
+
+/*
+ * Derived from Mesa's GLframebuffer class.
+ */
+struct GLFBDevBufferRec {
+ GLframebuffer glframebuffer; /* base class */
+ GLFBDevVisualPtr visual;
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+ size_t size; /* color buffer size in bytes */
+ GLuint bytesPerPixel;
+};
+
+/*
+ * Derived from Mesa's GLcontext class.
+ */
+struct GLFBDevContextRec {
+ GLcontext glcontext; /* base class */
+ GLFBDevVisualPtr visual;
+ GLFBDevBufferPtr drawBuffer;
+ GLFBDevBufferPtr readBuffer;
+ GLFBDevBufferPtr curBuffer;
+};
+
+/*
+ * Derived from Mesa's gl_renderbuffer class.
+ */
+struct GLFBDevRenderbufferRec {
+ struct gl_renderbuffer Base;
+ GLubyte *bottom; /* pointer to last row */
+ GLuint rowStride; /* in bytes */
+ GLboolean mallocedBuffer;
+};
+
+
+
+#define GLFBDEV_CONTEXT(CTX) ((GLFBDevContextPtr) (CTX))
+#define GLFBDEV_BUFFER(BUF) ((GLFBDevBufferPtr) (BUF))
+
+
+/**********************************************************************/
+/* Internal device driver functions */
+/**********************************************************************/
+
+
+static const GLubyte *
+get_string(GLcontext *ctx, GLenum pname)
+{
+ (void) ctx;
+ switch (pname) {
+ case GL_RENDERER:
+ return (const GLubyte *) "Mesa glfbdev";
+ 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 );
+}
+
+
+static void
+get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
+{
+ const GLFBDevBufferPtr fbdevbuffer = GLFBDEV_BUFFER(buffer);
+ *width = fbdevbuffer->var.xres_virtual;
+ *height = fbdevbuffer->var.yres_virtual;
+}
+
+
+static void
+viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ /* poll for window size change and realloc software Z/stencil/etc if needed */
+ _mesa_ResizeBuffersMESA();
+}
+
+
+/* specifies the buffer for swrast span rendering/reading */
+static void
+set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit )
+{
+ /* this is a no-op when using the new gl_renderbuffer span functions. */
+}
+
+
+/*
+ * Generate code for span functions.
+ */
+
+/* 24-bit BGR */
+#define NAME(PREFIX) PREFIX##_B8G8R8
+#define FORMAT GL_RGBA8
+#define SPAN_VARS \
+ struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = frb->bottom - (Y) * frb->rowStride + (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] = CHAN_MAX
+
+#include "swrast/s_spantemp2.h"
+
+
+/* 32-bit BGRA */
+#define NAME(PREFIX) PREFIX##_B8G8R8A8
+#define FORMAT GL_RGBA8
+#define SPAN_VARS \
+ struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = frb->bottom - (Y) * frb->rowStride + (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 FETCH_PIXEL(DST, SRC) \
+ DST[RCOMP] = SRC[2]; \
+ DST[GCOMP] = SRC[1]; \
+ DST[BCOMP] = SRC[0]; \
+ DST[ACOMP] = SRC[3]
+
+#include "swrast/s_spantemp2.h"
+
+
+/* 16-bit BGR (XXX implement dithering someday) */
+#define NAME(PREFIX) PREFIX##_B5G6R5
+#define FORMAT GL_RGBA8
+#define SPAN_VARS \
+ struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (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] = CHAN_MAX
+
+#include "swrast/s_spantemp2.h"
+
+
+/* 15-bit BGR (XXX implement dithering someday) */
+#define NAME(PREFIX) PREFIX##_B5G5R5
+#define FORMAT GL_RGBA8
+#define SPAN_VARS \
+ struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLushort *P = (GLushort *) (frb->bottom - (Y) * frb->rowStride + (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] = CHAN_MAX
+
+#include "swrast/s_spantemp2.h"
+
+
+/* 8-bit color index */
+#define NAME(PREFIX) PREFIX##_CI8
+#define FORMAT GL_COLOR_INDEX8_EXT
+#define SPAN_VARS \
+ struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = frb->bottom - (Y) * frb->rowStride + (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_spantemp2.h"
+
+
+
+
+/**********************************************************************/
+/* Public API functions */
+/**********************************************************************/
+
+
+const char *
+glFBDevGetString( int str )
+{
+ switch (str) {
+ case GLFBDEV_VENDOR:
+ return "Mesa Project";
+ case GLFBDEV_VERSION:
+ return "1.0.0";
+ default:
+ return NULL;
+ }
+}
+
+
+const GLFBDevProc
+glFBDevGetProcAddress( const char *procName )
+{
+ struct name_address {
+ const char *name;
+ const GLFBDevProc func;
+ };
+ static const struct name_address functions[] = {
+ { "glFBDevGetString", (GLFBDevProc) glFBDevGetString },
+ { "glFBDevGetProcAddress", (GLFBDevProc) glFBDevGetProcAddress },
+ { "glFBDevCreateVisual", (GLFBDevProc) glFBDevCreateVisual },
+ { "glFBDevDestroyVisual", (GLFBDevProc) glFBDevDestroyVisual },
+ { "glFBDevGetVisualAttrib", (GLFBDevProc) glFBDevGetVisualAttrib },
+ { "glFBDevCreateBuffer", (GLFBDevProc) glFBDevCreateBuffer },
+ { "glFBDevDestroyBuffer", (GLFBDevProc) glFBDevDestroyBuffer },
+ { "glFBDevGetBufferAttrib", (GLFBDevProc) glFBDevGetBufferAttrib },
+ { "glFBDevGetCurrentDrawBuffer", (GLFBDevProc) glFBDevGetCurrentDrawBuffer },
+ { "glFBDevGetCurrentReadBuffer", (GLFBDevProc) glFBDevGetCurrentReadBuffer },
+ { "glFBDevSwapBuffers", (GLFBDevProc) glFBDevSwapBuffers },
+ { "glFBDevCreateContext", (GLFBDevProc) glFBDevCreateContext },
+ { "glFBDevDestroyContext", (GLFBDevProc) glFBDevDestroyContext },
+ { "glFBDevGetContextAttrib", (GLFBDevProc) glFBDevGetContextAttrib },
+ { "glFBDevGetCurrentContext", (GLFBDevProc) glFBDevGetCurrentContext },
+ { "glFBDevMakeCurrent", (GLFBDevProc) glFBDevMakeCurrent },
+ { NULL, NULL }
+ };
+ const struct name_address *entry;
+ for (entry = functions; entry->name; entry++) {
+ if (_mesa_strcmp(entry->name, procName) == 0) {
+ return entry->func;
+ }
+ }
+ return _glapi_get_proc_address(procName);
+}
+
+
+GLFBDevVisualPtr
+glFBDevCreateVisual( const struct fb_fix_screeninfo *fixInfo,
+ const struct fb_var_screeninfo *varInfo,
+ const int *attribs )
+{
+ GLFBDevVisualPtr vis;
+ const int *attrib;
+ GLboolean rgbFlag = GL_TRUE, dbFlag = GL_FALSE, stereoFlag = GL_FALSE;
+ GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0;
+ GLint indexBits = 0, depthBits = 0, stencilBits = 0;
+ GLint accumRedBits = 0, accumGreenBits = 0;
+ GLint accumBlueBits = 0, accumAlphaBits = 0;
+ GLint numSamples = 0;
+
+ ASSERT(fixInfo);
+ ASSERT(varInfo);
+
+ vis = CALLOC_STRUCT(GLFBDevVisualRec);
+ if (!vis)
+ return NULL;
+
+ vis->fix = *fixInfo; /* struct assignment */
+ vis->var = *varInfo; /* struct assignment */
+
+ for (attrib = attribs; attrib && *attrib != GLFBDEV_NONE; attrib++) {
+ switch (*attrib) {
+ case GLFBDEV_DOUBLE_BUFFER:
+ dbFlag = GL_TRUE;
+ break;
+ case GLFBDEV_COLOR_INDEX:
+ rgbFlag = GL_FALSE;
+ break;
+ case GLFBDEV_DEPTH_SIZE:
+ depthBits = attrib[1];
+ attrib++;
+ break;
+ case GLFBDEV_STENCIL_SIZE:
+ stencilBits = attrib[1];
+ attrib++;
+ break;
+ case GLFBDEV_ACCUM_SIZE:
+ accumRedBits = accumGreenBits = accumBlueBits = accumAlphaBits
+ = attrib[1];
+ attrib++;
+ break;
+ case GLFBDEV_LEVEL:
+ /* ignored for now */
+ break;
+ default:
+ /* unexpected token */
+ _mesa_free(vis);
+ return NULL;
+ }
+ }
+
+ if (rgbFlag) {
+ redBits = varInfo->red.length;
+ greenBits = varInfo->green.length;
+ blueBits = varInfo->blue.length;
+ alphaBits = varInfo->transp.length;
+
+ if ((fixInfo->visual == FB_VISUAL_TRUECOLOR ||
+ fixInfo->visual == FB_VISUAL_DIRECTCOLOR)
+ && varInfo->bits_per_pixel == 24
+ && varInfo->red.offset == 16
+ && varInfo->green.offset == 8
+ && varInfo->blue.offset == 0) {
+ vis->pixelFormat = PF_B8G8R8;
+ }
+ else if ((fixInfo->visual == FB_VISUAL_TRUECOLOR ||
+ fixInfo->visual == FB_VISUAL_DIRECTCOLOR)
+ && varInfo->bits_per_pixel == 32
+ && varInfo->red.offset == 16
+ && varInfo->green.offset == 8
+ && varInfo->blue.offset == 0
+ && varInfo->transp.offset == 24) {
+ vis->pixelFormat = PF_B8G8R8A8;
+ }
+ else if ((fixInfo->visual == FB_VISUAL_TRUECOLOR ||
+ fixInfo->visual == FB_VISUAL_DIRECTCOLOR)
+ && varInfo->bits_per_pixel == 16
+ && varInfo->red.offset == 11
+ && varInfo->green.offset == 5
+ && varInfo->blue.offset == 0) {
+ vis->pixelFormat = PF_B5G6R5;
+ }
+ else if ((fixInfo->visual == FB_VISUAL_TRUECOLOR ||
+ fixInfo->visual == FB_VISUAL_DIRECTCOLOR)
+ && varInfo->bits_per_pixel == 16
+ && varInfo->red.offset == 10
+ && varInfo->green.offset == 5
+ && varInfo->blue.offset == 0) {
+ vis->pixelFormat = PF_B5G5R5;
+ }
+ else {
+ _mesa_problem(NULL, "Unsupported fbdev RGB visual/bitdepth!\n");
+ /*
+ printf("fixInfo->visual = 0x%x\n", fixInfo->visual);
+ printf("varInfo->bits_per_pixel = %d\n", varInfo->bits_per_pixel);
+ printf("varInfo->red.offset = %d\n", varInfo->red.offset);
+ printf("varInfo->green.offset = %d\n", varInfo->green.offset);
+ printf("varInfo->blue.offset = %d\n", varInfo->blue.offset);
+ */
+ _mesa_free(vis);
+ return NULL;
+ }
+ }
+ else {
+ indexBits = varInfo->bits_per_pixel;
+ if ((fixInfo->visual == FB_VISUAL_PSEUDOCOLOR ||
+ fixInfo->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
+ && varInfo->bits_per_pixel == 8) {
+ vis->pixelFormat = PF_CI8;
+ }
+ else {
+ _mesa_problem(NULL, "Unsupported fbdev CI visual/bitdepth!\n");
+ _mesa_free(vis);
+ return NULL;
+ }
+ }
+
+ if (!_mesa_initialize_visual(&vis->glvisual, rgbFlag, dbFlag, stereoFlag,
+ redBits, greenBits, blueBits, alphaBits,
+ indexBits, depthBits, stencilBits,
+ accumRedBits, accumGreenBits,
+ accumBlueBits, accumAlphaBits,
+ numSamples)) {
+ /* something was invalid */
+ _mesa_free(vis);
+ return NULL;
+ }
+
+ return vis;
+}
+
+
+void
+glFBDevDestroyVisual( GLFBDevVisualPtr visual )
+{
+ if (visual)
+ _mesa_free(visual);
+}
+
+
+int
+glFBDevGetVisualAttrib( const GLFBDevVisualPtr visual, int attrib)
+{
+ /* XXX unfinished */
+ (void) visual;
+ (void) attrib;
+ return -1;
+}
+
+
+static void
+delete_renderbuffer(struct gl_renderbuffer *rb)
+{
+ struct GLFBDevRenderbufferRec *frb = (struct GLFBDevRenderbufferRec *) rb;
+ if (frb->mallocedBuffer) {
+ _mesa_free(frb->Base.Data);
+ }
+ _mesa_free(frb);
+}
+
+
+static GLboolean
+renderbuffer_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat, GLuint width, GLuint height)
+{
+ /* no-op: the renderbuffer storage is allocated just once when it's
+ * created. Never resized or reallocated.
+ */
+ return GL_TRUE;
+}
+
+
+static struct GLFBDevRenderbufferRec *
+new_glfbdev_renderbuffer(void *bufferStart, int pixelFormat)
+{
+ struct GLFBDevRenderbufferRec *rb = CALLOC_STRUCT(GLFBDevRenderbufferRec);
+ if (rb) {
+ GLuint name = 0;
+ _mesa_init_renderbuffer(&rb->Base, name);
+
+ rb->Base.Delete = delete_renderbuffer;
+ rb->Base.AllocStorage = renderbuffer_storage;
+
+ if (pixelFormat == PF_B8G8R8) {
+ rb->Base.GetRow = get_row_B8G8R8;
+ rb->Base.GetValues = get_values_B8G8R8;
+ rb->Base.PutRow = put_row_B8G8R8;
+ rb->Base.PutMonoRow = put_mono_row_B8G8R8;
+ rb->Base.PutValues = put_values_B8G8R8;
+ rb->Base.PutMonoValues = put_mono_values_B8G8R8;
+ }
+ else if (pixelFormat == PF_B8G8R8A8) {
+ rb->Base.GetRow = get_row_B8G8R8A8;
+ rb->Base.GetValues = get_values_B8G8R8A8;
+ rb->Base.PutRow = put_row_B8G8R8A8;
+ rb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
+ rb->Base.PutValues = put_values_B8G8R8A8;
+ rb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
+ }
+ else if (pixelFormat == PF_B5G6R5) {
+ rb->Base.GetRow = get_row_B5G6R5;
+ rb->Base.GetValues = get_values_B5G6R5;
+ rb->Base.PutRow = put_row_B5G6R5;
+ rb->Base.PutMonoRow = put_mono_row_B5G6R5;
+ rb->Base.PutValues = put_values_B5G6R5;
+ rb->Base.PutMonoValues = put_mono_values_B5G6R5;
+ }
+ else if (pixelFormat == PF_B5G5R5) {
+ rb->Base.GetRow = get_row_B5G5R5;
+ rb->Base.GetValues = get_values_B5G5R5;
+ rb->Base.PutRow = put_row_B5G5R5;
+ rb->Base.PutMonoRow = put_mono_row_B5G5R5;
+ rb->Base.PutValues = put_values_B5G5R5;
+ rb->Base.PutMonoValues = put_mono_values_B5G5R5;
+ }
+ else if (pixelFormat == PF_CI8) {
+ rb->Base.GetRow = get_row_CI8;
+ rb->Base.GetValues = get_values_CI8;
+ rb->Base.PutRow = put_row_CI8;
+ rb->Base.PutMonoRow = put_mono_row_CI8;
+ rb->Base.PutValues = put_values_CI8;
+ rb->Base.PutMonoValues = put_mono_values_CI8;
+ }
+
+ if (pixelFormat == PF_CI8) {
+ rb->Base.InternalFormat = GL_COLOR_INDEX8_EXT;
+ rb->Base._BaseFormat = GL_COLOR_INDEX;
+ }
+ else {
+ rb->Base.InternalFormat = GL_RGBA;
+ rb->Base._BaseFormat = GL_RGBA;
+ }
+ rb->Base.DataType = GL_UNSIGNED_BYTE;
+ rb->Base.Data = bufferStart;
+ }
+ return rb;
+}
+
+
+GLFBDevBufferPtr
+glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
+ const struct fb_var_screeninfo *varInfo,
+ const GLFBDevVisualPtr visual,
+ void *frontBuffer, void *backBuffer, size_t size )
+{
+ struct GLFBDevRenderbufferRec *frontrb, *backrb;
+ GLFBDevBufferPtr buf;
+
+ ASSERT(visual);
+ ASSERT(frontBuffer);
+ ASSERT(size > 0);
+
+ if (visual->fix.visual != fixInfo->visual ||
+ visual->fix.type != fixInfo->type ||
+ visual->var.bits_per_pixel != varInfo->bits_per_pixel ||
+ visual->var.grayscale != varInfo->grayscale ||
+ visual->var.red.offset != varInfo->red.offset ||
+ visual->var.green.offset != varInfo->green.offset ||
+ visual->var.blue.offset != varInfo->blue.offset ||
+ visual->var.transp.offset != varInfo->transp.offset) {
+ /* visual mismatch! */
+ return NULL;
+ }
+
+ buf = CALLOC_STRUCT(GLFBDevBufferRec);
+ if (!buf)
+ return NULL;
+
+ /* basic framebuffer setup */
+ _mesa_initialize_framebuffer(&buf->glframebuffer, &visual->glvisual);
+ /* add front renderbuffer */
+ frontrb = new_glfbdev_renderbuffer(frontBuffer, visual->pixelFormat);
+ _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT,
+ &frontrb->Base);
+ /* add back renderbuffer */
+ if (visual->glvisual.doubleBufferMode) {
+ backrb = new_glfbdev_renderbuffer(backBuffer, visual->pixelFormat);
+ _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT,
+ &backrb->Base);
+ }
+ /* add software renderbuffers */
+ _mesa_add_soft_renderbuffers(&buf->glframebuffer,
+ GL_FALSE, /* color */
+ visual->glvisual.haveDepthBuffer,
+ visual->glvisual.haveStencilBuffer,
+ visual->glvisual.haveAccumBuffer,
+ GL_FALSE, /* alpha */
+ GL_FALSE /* aux bufs */);
+
+
+
+ buf->fix = *fixInfo; /* struct assignment */
+ buf->var = *varInfo; /* struct assignment */
+ buf->visual = visual; /* ptr assignment */
+ buf->size = size;
+ buf->bytesPerPixel = visual->var.bits_per_pixel / 8;
+ frontrb->rowStride = visual->var.xres_virtual * buf->bytesPerPixel;
+ frontrb->bottom = (GLubyte *) frontrb->Base.Data
+ + (visual->var.yres_virtual - 1) * frontrb->rowStride;
+
+ if (visual->glvisual.doubleBufferMode) {
+ if (!backBuffer) {
+ /* malloc a back buffer */
+ backrb->Base.Data = _mesa_malloc(size);
+ if (!backrb->Base.Data) {
+ _mesa_free_framebuffer_data(&buf->glframebuffer);
+ _mesa_free(buf);
+ return NULL;
+ }
+ backrb->mallocedBuffer = GL_TRUE;
+ }
+ backrb->rowStride = frontrb->rowStride;
+ backrb->bottom = (GLubyte *) backrb->Base.Data
+ + (visual->var.yres_virtual - 1) * backrb->rowStride;
+ }
+ else {
+ backrb->bottom = NULL;
+ backrb->rowStride = 0;
+ }
+
+ return buf;
+}
+
+
+void
+glFBDevDestroyBuffer( GLFBDevBufferPtr buffer )
+{
+ if (buffer) {
+ /* check if destroying the current buffer */
+ GLFBDevBufferPtr curDraw = glFBDevGetCurrentDrawBuffer();
+ GLFBDevBufferPtr curRead = glFBDevGetCurrentReadBuffer();
+ if (buffer == curDraw || buffer == curRead) {
+ glFBDevMakeCurrent( NULL, NULL, NULL);
+ }
+ /* free the software depth, stencil, accum buffers */
+ _mesa_free_framebuffer_data(&buffer->glframebuffer);
+ _mesa_free(buffer);
+ }
+}
+
+
+int
+glFBDevGetBufferAttrib( const GLFBDevBufferPtr buffer, int attrib)
+{
+ (void) buffer;
+ (void) attrib;
+ return -1;
+}
+
+
+GLFBDevBufferPtr
+glFBDevGetCurrentDrawBuffer( void )
+{
+ GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
+ if (fbdevctx)
+ return fbdevctx->drawBuffer;
+ else
+ return NULL;
+}
+
+
+GLFBDevBufferPtr
+glFBDevGetCurrentReadBuffer( void )
+{
+ GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
+ if (fbdevctx)
+ return fbdevctx->readBuffer;
+ else
+ return NULL;
+}
+
+
+void
+glFBDevSwapBuffers( GLFBDevBufferPtr buffer )
+{
+ GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
+ struct GLFBDevRenderbufferRec *frontrb = (struct GLFBDevRenderbufferRec *)
+ buffer->glframebuffer.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ struct GLFBDevRenderbufferRec *backrb = (struct GLFBDevRenderbufferRec *)
+ buffer->glframebuffer.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+
+ if (!buffer || !buffer->visual->glvisual.doubleBufferMode)
+ return;
+
+ /* check if swapping currently bound buffer */
+ if (fbdevctx->drawBuffer == buffer) {
+ /* flush pending rendering */
+ _mesa_notifySwapBuffers(&fbdevctx->glcontext);
+ }
+
+ ASSERT(frontrb->Base.Data);
+ ASSERT(backrb->Base.Data);
+ _mesa_memcpy(frontrb->Base.Data, backrb->Base.Data, buffer->size);
+}
+
+
+GLFBDevContextPtr
+glFBDevCreateContext( const GLFBDevVisualPtr visual, GLFBDevContextPtr share )
+{
+ GLFBDevContextPtr ctx;
+ GLcontext *glctx;
+ struct dd_function_table functions;
+
+ ASSERT(visual);
+
+ ctx = CALLOC_STRUCT(GLFBDevContextRec);
+ if (!ctx)
+ return NULL;
+
+ /* build table of device driver functions */
+ _mesa_init_driver_functions(&functions);
+ functions.GetString = get_string;
+ functions.UpdateState = update_state;
+ functions.GetBufferSize = get_buffer_size;
+ functions.Viewport = viewport;
+
+ if (!_mesa_initialize_context(&ctx->glcontext, &visual->glvisual,
+ share ? &share->glcontext : NULL,
+ &functions, (void *) ctx)) {
+ _mesa_free(ctx);
+ return NULL;
+ }
+
+ ctx->visual = visual;
+
+ /* Create module contexts */
+ glctx = (GLcontext *) &ctx->glcontext;
+ _swrast_CreateContext( glctx );
+ _ac_CreateContext( glctx );
+ _tnl_CreateContext( glctx );
+ _swsetup_CreateContext( glctx );
+ _swsetup_Wakeup( glctx );
+
+ /* swrast init */
+ {
+ struct swrast_device_driver *swdd;
+ swdd = _swrast_GetDeviceDriverReference( glctx );
+ swdd->SetBuffer = set_buffer;
+
+ /* no longer used */
+ swdd->WriteRGBASpan = NULL;
+ swdd->WriteRGBSpan = NULL;
+ swdd->WriteMonoRGBASpan = NULL;
+ swdd->WriteRGBAPixels = NULL;
+ swdd->WriteMonoRGBAPixels = NULL;
+ swdd->ReadRGBASpan = NULL;
+ swdd->ReadRGBAPixels = NULL;
+ }
+
+ /* use default TCL pipeline */
+ {
+ TNLcontext *tnl = TNL_CONTEXT(glctx);
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
+ }
+
+ _mesa_enable_sw_extensions(glctx);
+
+ return ctx;
+}
+
+
+void
+glFBDevDestroyContext( GLFBDevContextPtr context )
+{
+ GLFBDevContextPtr fbdevctx = glFBDevGetCurrentContext();
+
+ if (context) {
+ if (fbdevctx == context) {
+ /* destroying current context */
+ _mesa_make_current(NULL, NULL, NULL);
+ _mesa_notifyDestroy(&context->glcontext);
+ }
+ _mesa_free_context_data(&context->glcontext);
+ _mesa_free(context);
+ }
+}
+
+
+int
+glFBDevGetContextAttrib( const GLFBDevContextPtr context, int attrib)
+{
+ (void) context;
+ (void) attrib;
+ return -1;
+}
+
+
+GLFBDevContextPtr
+glFBDevGetCurrentContext( void )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return (GLFBDevContextPtr) ctx;
+}
+
+
+int
+glFBDevMakeCurrent( GLFBDevContextPtr context,
+ GLFBDevBufferPtr drawBuffer,
+ GLFBDevBufferPtr readBuffer )
+{
+ if (context && drawBuffer && readBuffer) {
+ /* Make sure the context's visual and the buffers' visuals match.
+ * XXX we might do this by comparing specific fields like bits_per_pixel,
+ * visual, etc. in the future.
+ */
+ if (context->visual != drawBuffer->visual ||
+ context->visual != readBuffer->visual) {
+ return 0;
+ }
+ _mesa_make_current( &context->glcontext,
+ &drawBuffer->glframebuffer,
+ &readBuffer->glframebuffer );
+ context->drawBuffer = drawBuffer;
+ context->readBuffer = readBuffer;
+ context->curBuffer = drawBuffer;
+ }
+ else {
+ /* unbind */
+ _mesa_make_current( NULL, NULL, NULL );
+ }
+
+ return 1;
+}
+
+#endif