📄 fb_dri.c
字号:
/* * 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 "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"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 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 );}/** * Called by ctx->Driver.GetBufferSize from in core Mesa to query the * current framebuffer size. */static voidget_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 voidupdateFramebufferSize(GLcontext *ctx){ fbContextPtr fbmesa = FB_CONTEXT(ctx); struct gl_framebuffer *fb = ctx->WinSysDrawBuffer; if (fbmesa->dri.drawable->w != fb->Width || fbmesa->dri.drawable->h != fb->Height) { driUpdateFramebufferSize(ctx, fbmesa->dri.drawable); }}static voidviewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h){ /* XXX this should be called after we acquire the DRI lock, not here */ updateFramebufferSize(ctx);}static voidinit_core_functions( struct dd_function_table *functions ){ functions->GetString = get_string; functions->UpdateState = update_state; 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"voidfbSetSpanFunctions(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 GLbooleanfbInitDriver( __DRIscreenPrivate *sPriv ){ sPriv->private = NULL; return GL_TRUE;}static voidfbDestroyScreen( __DRIscreenPrivate *sPriv ){}/* Create the device specific context. */static GLbooleanfbCreateContext( 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 ); _vbo_CreateContext( ctx ); _tnl_CreateContext( ctx ); _swsetup_CreateContext( ctx ); _swsetup_Wakeup( ctx ); /* use default TCL pipeline */ { TNLcontext *tnl = TNL_CONTEXT(ctx); tnl->Driver.RunPipeline = _tnl_run_pipeline; } _mesa_enable_sw_extensions(ctx); return GL_TRUE;}static voidfbDestroyContext( __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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -