📄 fb_egl.c
字号:
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 ); _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 c->Base.Handle;}static EGLSurfacefbCreateWindowSurface(_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 EGLSurfacefbCreatePixmapSurface(_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 EGLSurfacefbCreatePbufferSurface(_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 EGLBooleanfbDestroySurface(_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 EGLBooleanfbDestroyContext(_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 EGLBooleanfbMakeCurrent(_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 EGLSurfacefbCreateScreenSurfaceMESA(_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, display->pFB, bytesPerPixel, origin, stride, NULL); fbSetSpanFunctions(drb, &vis); _mesa_add_renderbuffer(surface->mesa_framebuffer, BUFFER_FRONT_LEFT, &drb->Base); } /* back color renderbuffer */ if (vis.doubleBufferMode) { GLubyte *backBuf = _mesa_malloc(stride * height); driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, backBuf, bytesPerPixel, origin, stride, NULL); fbSetSpanFunctions(drb, &vis); _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 EGLBooleanfbShowSurfaceMESA(_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 EGLBooleanfbSwapBuffers(_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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -