⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fb_egl.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Test egl driver for fb_dri.so */#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dirent.h> #include <errno.h>#include <fcntl.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <linux/fb.h>#include "utils.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"#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 voidfbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis);/** * 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;   struct {      __DRIcontextPrivate *context;	      __DRIscreenPrivate *screen;	      __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */   } dri;} fbContext, *fbContextPtr;#define FB_CONTEXT(ctx)		((fbContextPtr)(ctx->DriverCtx))static EGLBooleanfbFillInConfigs(_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 EGLBooleanfbSetupFramebuffer(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 EGLBooleanfbInitialize(_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 EGLBooleanfbTerminate(_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 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 ){   *width  = buffer->Width;   *height = buffer->Height;}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 */}static EGLContextfbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list){   GLcontext *ctx;   _EGLConfig *conf;   fbContext *c;   _EGLDisplay *disp = _eglLookupDisplay(dpy);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -