📄 glfbdev.c
字号:
/* * Mesa 3-D graphics library * Version: 7.1 * * Copyright (C) 1999-2007 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 "vbo/vbo.h"#include "swrast/swrast.h"#include "swrast_setup/swrast_setup.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "tnl/t_pipeline.h"#include "drivers/common/driverfuncs.h"/** * Pixel formats we support: */#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;};/**********************************************************************//* 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 voidupdate_state( GLcontext *ctx, GLuint new_state ){ /* not much to do here - pass it on */ _swrast_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); _vbo_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state );}static voidget_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ){ const GLFBDevBufferPtr fbdevbuffer = (GLFBDevBufferPtr) buffer; *width = fbdevbuffer->var.xres; *height = fbdevbuffer->var.yres;}/** * We only implement this function as a mechanism to check if the * framebuffer size has changed (and update corresponding state). */static voidviewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h){ GLuint newWidth, newHeight; GLframebuffer *buffer; buffer = ctx->WinSysDrawBuffer; get_buffer_size( buffer, &newWidth, &newHeight ); if (buffer->Width != newWidth || buffer->Height != newHeight) { _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight ); } buffer = ctx->WinSysReadBuffer; get_buffer_size( buffer, &newWidth, &newHeight ); if (buffer->Width != newWidth || buffer->Height != newHeight) { _mesa_resize_framebuffer(ctx, buffer, newWidth, newHeight ); }}/* * Generate code for span functions. *//* 24-bit BGR */#define NAME(PREFIX) PREFIX##_B8G8R8#define RB_TYPE GLubyte#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_spantemp.h"/* 32-bit BGRA */#define NAME(PREFIX) PREFIX##_B8G8R8A8#define RB_TYPE GLubyte#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_spantemp.h"/* 16-bit BGR (XXX implement dithering someday) */#define NAME(PREFIX) PREFIX##_B5G6R5#define RB_TYPE GLubyte#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_spantemp.h"/* 15-bit BGR (XXX implement dithering someday) */#define NAME(PREFIX) PREFIX##_B5G5R5#define RB_TYPE GLubyte#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_spantemp.h"/* 8-bit color index */#define NAME(PREFIX) PREFIX##_CI8#define CI_MODE#define RB_TYPE GLubyte#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_spantemp.h"/**********************************************************************//* Public API functions *//**********************************************************************/const char *glFBDevGetString( int str ){ switch (str) { case GLFBDEV_VENDOR: return "Mesa Project"; case GLFBDEV_VERSION: return "1.0.1"; default: return NULL; }}GLFBDevProcglFBDevGetProcAddress( 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);}GLFBDevVisualPtrglFBDevCreateVisual( 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; case GLFBDEV_MULTISAMPLE: numSamples = attrib[1]; attrib++; 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) { if (varInfo->bits_per_pixel == 24 && varInfo->red.offset == 16 && varInfo->green.offset == 8 && varInfo->blue.offset == 0) { vis->pixelFormat = PF_B8G8R8; } else if (varInfo->bits_per_pixel == 32 && varInfo->red.offset == 16 && varInfo->green.offset == 8 && varInfo->blue.offset == 0) { vis->pixelFormat = PF_B8G8R8A8; } else if (varInfo->bits_per_pixel == 16 && varInfo->red.offset == 11 && varInfo->green.offset == 5 && varInfo->blue.offset == 0) { vis->pixelFormat = PF_B5G6R5; } else if (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"); _mesa_free(vis); return NULL; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -