SurfaceFlinger调用framebuffer模块、gralloc模块流程(3)
来源:互联网 发布:unity3d vs2017 编辑:程序博客网 时间:2024/06/05 23:03
1:frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp
//readyToRun初始化整个显示系统status_t SurfaceFlinger::readyToRun(){ LOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W..."); // we only support one display currently int dpy = 0; { // initialize the main display //(1)初始化主显 GraphicPlane& plane(graphicPlane(dpy)); DisplayHardware* const hw = new DisplayHardware(this, dpy); plane.setDisplayHardware(hw); } // create the shared control-block //(2)创建共享内存控制块 mServerHeap = new MemoryHeapBase(4096, MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap"); LOGE_IF(mServerHeap==0, "can't create shared memory dealer"); mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase()); LOGE_IF(mServerCblk==0, "can't get to shared control block's address"); new(mServerCblk) surface_flinger_cblk_t; // initialize primary screen初始化主屏 // (other display should be initialized in the same manner, but // asynchronously, as they could come and go. None of this is supported // yet). const GraphicPlane& plane(graphicPlane(dpy)); const DisplayHardware& hw = plane.displayHardware(); const uint32_t w = hw.getWidth(); const uint32_t h = hw.getHeight(); const uint32_t f = hw.getFormat(); hw.makeCurrent(); // initialize the shared control block初始化共享控制块 mServerCblk->connected |= 1<<dpy; display_cblk_t* dcblk = mServerCblk->displays + dpy; memset(dcblk, 0, sizeof(display_cblk_t)); dcblk->w = plane.getWidth(); dcblk->h = plane.getHeight(); dcblk->format = f; dcblk->orientation = ISurfaceComposer::eOrientationDefault; dcblk->xdpi = hw.getDpiX(); dcblk->ydpi = hw.getDpiY(); dcblk->fps = hw.getRefreshRate(); dcblk->density = hw.getDensity();#ifdef OMAP_ENHANCEMENT dcblk->maxTex = hw.getMaxTextureSize();#endif // Initialize OpenGL|ES glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glPixelStorei(GL_PACK_ALIGNMENT, 4); glEnableClientState(GL_VERTEX_ARRAY); glEnable(GL_SCISSOR_TEST); glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_CULL_FACE); const uint16_t g0 = pack565(0x0F,0x1F,0x0F); const uint16_t g1 = pack565(0x17,0x2f,0x17); const uint16_t wormholeTexData[4] = { g0, g1, g1, g0 }; glGenTextures(1, &mWormholeTexName); glBindTexture(GL_TEXTURE_2D, mWormholeTexName); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, wormholeTexData); const uint16_t protTexData[] = { pack565(0x03, 0x03, 0x03) }; glGenTextures(1, &mProtectedTexName); glBindTexture(GL_TEXTURE_2D, mProtectedTexName); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, protTexData); glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // put the origin in the left-bottom corner //左下角为原点 glOrthof(0, w, 0, h, 0, 1); // l=0, r=w ; b=0, t=h mReadyToRunBarrier.open(); /* * We're now ready to accept clients... */ // start boot animation property_set("ctl.start", "bootanim"); return NO_ERROR;}
2:frameworks/base/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
/* * Initialize the display to the specified values. * *///调用了DisplayHardware::init()函数DisplayHardware::DisplayHardware( const sp<SurfaceFlinger>& flinger, uint32_t dpy) : DisplayHardwareBase(flinger, dpy), mFlinger(flinger), mFlags(0), mHwc(0){ init(dpy);}--------------------------------------------void DisplayHardware::init(uint32_t dpy){ mNativeWindow = new FramebufferNativeWindow(); framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); if (!fbDev) { LOGE("Display subsystem failed to initialize. check logs. exiting..."); exit(0); } int format; ANativeWindow const * const window = mNativeWindow.get(); window->query(window, NATIVE_WINDOW_FORMAT, &format); mDpiX = mNativeWindow->xdpi; mDpiY = mNativeWindow->ydpi; mRefreshRate = fbDev->fps;/* FIXME: this is a temporary HACK until we are able to report the refresh rate * properly from the HAL. The WindowManagerService now relies on this value. */#ifndef REFRESH_RATE mRefreshRate = fbDev->fps;#else mRefreshRate = REFRESH_RATE;#warning "refresh rate set via makefile to REFRESH_RATE"#endif EGLint w, h, dummy; EGLint numConfigs=0; EGLSurface surface; EGLContext context; EGLBoolean result; status_t err; // initialize EGL EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT,#ifdef OMAP_ENHANCEMENT_S3D EGL_STENCIL_SIZE, 1,#endif EGL_NONE, 0, EGL_NONE }; // debug: disable h/w rendering char property[PROPERTY_VALUE_MAX]; if (property_get("debug.sf.hw", property, NULL) > 0) { if (atoi(property) == 0) { LOGW("H/W composition disabled");#ifdef OMAP_ENHANCEMENT_S3D attribs[4] = EGL_CONFIG_CAVEAT; attribs[5] = EGL_SLOW_CONFIG;#else attribs[2] = EGL_CONFIG_CAVEAT; attribs[3] = EGL_SLOW_CONFIG;#endif } } // TODO: all the extensions below should be queried through // eglGetProcAddress(). EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, NULL, NULL); eglGetConfigs(display, NULL, 0, &numConfigs); EGLConfig config = NULL; err = selectConfigForPixelFormat(display, attribs, format, &config); LOGE_IF(err, "couldn't find an EGLConfig matching the screen format"); EGLint r,g,b,a; eglGetConfigAttrib(display, config, EGL_RED_SIZE, &r); eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g); eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &b); eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a); if (mNativeWindow->isUpdateOnDemand()) { mFlags |= PARTIAL_UPDATES; } if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) { if (dummy == EGL_SLOW_CONFIG) mFlags |= SLOW_CONFIG; } /* * Create our main surface */ surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); eglQuerySurface(display, surface, EGL_WIDTH, &mWidth); eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight); if (mFlags & PARTIAL_UPDATES) { // if we have partial updates, we definitely don't need to // preserve the backbuffer, which may be costly. eglSurfaceAttrib(display, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); } if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) { if (dummy == EGL_BUFFER_PRESERVED) { mFlags |= BUFFER_PRESERVED; } } /* Read density from build-specific ro.sf.lcd_density property * except if it is overridden by qemu.sf.lcd_density. */ if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) { if (property_get("ro.sf.lcd_density", property, NULL) <= 0) { LOGW("ro.sf.lcd_density not defined, using 160 dpi by default."); strcpy(property, "160"); } } else { /* for the emulator case, reset the dpi values too */ mDpiX = mDpiY = atoi(property); } mDensity = atoi(property) * (1.0f/160.0f); /* * Create our OpenGL ES context */ EGLint contextAttributes[] = {#ifdef EGL_IMG_context_priority#ifdef HAS_CONTEXT_PRIORITY#warning "using EGL_IMG_context_priority" EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,#endif#endif EGL_NONE, EGL_NONE }; context = eglCreateContext(display, config, NULL, contextAttributes); mDisplay = display; mConfig = config; mSurface = surface; mContext = context; mFormat = fbDev->format; mPageFlipCount = 0; /* * Gather OpenGL ES extensions */ result = eglMakeCurrent(display, surface, surface, context); if (!result) { LOGE("Couldn't create a working GLES context. check logs. exiting..."); exit(0); } GLExtensions& extensions(GLExtensions::getInstance()); extensions.initWithGLStrings( glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION), glGetString(GL_EXTENSIONS), eglQueryString(display, EGL_VENDOR), eglQueryString(display, EGL_VERSION), eglQueryString(display, EGL_EXTENSIONS)); glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize); glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); LOGI("EGL informations:"); LOGI("# of configs : %d", numConfigs); LOGI("vendor : %s", extensions.getEglVendor()); LOGI("version : %s", extensions.getEglVersion()); LOGI("extensions: %s", extensions.getEglExtension()); LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported"); LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config); LOGI("OpenGL informations:"); LOGI("vendor : %s", extensions.getVendor()); LOGI("renderer : %s", extensions.getRenderer()); LOGI("version : %s", extensions.getVersion()); LOGI("extensions: %s", extensions.getExtension()); LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); LOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); LOGI("flags = %08x", mFlags); // Unbind the context from this thread eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); // initialize the H/W composer mHwc = new HWComposer(mFlinger); if (mHwc->initCheck() == NO_ERROR) { mHwc->setFrameBuffer(mDisplay, mSurface); }}
3:frameworks/base/libs/ui/FramebufferNativeWindow.cpp
/* * This implements the (main) framebuffer management. This class is used * mostly by SurfaceFlinger, but also by command line GL application. * * In fact this is an implementation of ANativeWindow on top of * the framebuffer. * * Currently it is pretty simple, it manages only two buffers (the front and * back buffer). * */ /* *这实现了(主要)帧缓冲区管理。这个类是主要由SurfaceFlinger使用,但也通过命令行GL应用程序。 *事实上这是一个实现ANativeWindow顶部的帧缓冲区。 *目前它是非常简单的,它管理着只有两个缓冲区(前后缓冲)。 */FramebufferNativeWindow::FramebufferNativeWindow() : BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false){/** *通过gralloc模块ID(GRALLOC_HARDWARE_MODULE_ID)得到gralloc模块;
*hardware/libhardware/include/hardware/gralloc.h中定义如下模块ID; *#define GRALLOC_HARDWARE_MODULE_ID "gralloc" * */ hw_module_t const* module; if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { int stride; int err; int i;/**hardware/libhardware/include/hardware/fb.h定义 *#define GRALLOC_HARDWARE_FB0 "fb0" 模块ID *framebuffer_device_t* fbDev; *最终调用:hardware/libhardware/modules/gralloc/framebuffer.cpp( fb_device_open())
*/ err = framebuffer_open(module, &fbDev); LOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));/** alloc_device_t* grDev; *最终调用:hardware/libhardware/modules/gralloc/gralloc.cpp (gralloc_device_open())
*/ err = gralloc_open(module, &grDev); LOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err)); // bail out if we can't initialize the modules //如果我们不能初始化模块则保释出来 if (!fbDev || !grDev) return; mUpdateOnDemand = (fbDev->setUpdateRect != 0); // initialize the buffer FIFO //双缓冲 mNumBuffers = NUM_FRAME_BUFFERS; mNumFreeBuffers = NUM_FRAME_BUFFERS; mBufferHead = mNumBuffers-1; for (i = 0; i < mNumBuffers; i++) { buffers[i] = new NativeBuffer( fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB); } for (i = 0; i < mNumBuffers; i++) { err = grDev->alloc(grDev, fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride); LOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s", i, fbDev->width, fbDev->height, strerror(-err)); if (err) { mNumBuffers = i; mNumFreeBuffers = i; mBufferHead = mNumBuffers-1; break; } }/*从framebuffer设备中获得常量*/ const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags; const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi; const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi; const_cast<int&>(ANativeWindow::minSwapInterval) = fbDev->minSwapInterval; const_cast<int&>(ANativeWindow::maxSwapInterval) = fbDev->maxSwapInterval; } else { LOGE("Couldn't get gralloc module"); } ANativeWindow::setSwapInterval = setSwapInterval; ANativeWindow::dequeueBuffer = dequeueBuffer; ANativeWindow::lockBuffer = lockBuffer; ANativeWindow::queueBuffer = queueBuffer; ANativeWindow::query = query; ANativeWindow::perform = perform;}
4:hardware/libhardware/modules/gralloc/framebuffer.cpp
int fb_device_open(hw_module_t const* module, const char* name, hw_device_t** device){ int status = -EINVAL; if (!strcmp(name, GRALLOC_HARDWARE_FB0)) { alloc_device_t* gralloc_device; status = gralloc_open(module, &gralloc_device); if (status < 0) return status; /* initialize our state here */ fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev)); memset(dev, 0, sizeof(*dev)); /* initialize the procs */ dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = 0; dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.common.close = fb_close; dev->device.setSwapInterval = fb_setSwapInterval; dev->device.post = fb_post; dev->device.setUpdateRect = 0; private_module_t* m = (private_module_t*)module; status = mapFrameBuffer(m); if (status >= 0) { int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3); int format = (m->info.bits_per_pixel == 32) ? HAL_PIXEL_FORMAT_RGBX_8888 : HAL_PIXEL_FORMAT_RGB_565; const_cast<uint32_t&>(dev->device.flags) = 0; const_cast<uint32_t&>(dev->device.width) = m->info.xres; const_cast<uint32_t&>(dev->device.height) = m->info.yres; const_cast<int&>(dev->device.stride) = stride; const_cast<int&>(dev->device.format) = format; const_cast<float&>(dev->device.xdpi) = m->xdpi; const_cast<float&>(dev->device.ydpi) = m->ydpi; const_cast<float&>(dev->device.fps) = m->fps; const_cast<int&>(dev->device.minSwapInterval) = 1; const_cast<int&>(dev->device.maxSwapInterval) = 1; *device = &dev->device.common; } } return status;}
/*****************************************************************************//**将物理地址映射到虚拟地址空间供应用程序使用*/int mapFrameBufferLocked(struct private_module_t* module){ // already initialized... if (module->framebuffer) { return 0; } char const * const device_template[] = { "/dev/graphics/fb%u", "/dev/fb%u", 0 }; int fd = -1; int i=0; char name[64]; while ((fd==-1) && device_template[i]) { snprintf(name, 64, device_template[i], 0); fd = open(name, O_RDWR, 0); i++; } if (fd < 0) return -errno; struct fb_fix_screeninfo finfo; if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)/*固定屏幕信息*/ return -errno; struct fb_var_screeninfo info; if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)/*变化屏幕信息*/ return -errno; info.reserved[0] = 0; info.reserved[1] = 0; info.reserved[2] = 0; info.xoffset = 0; info.yoffset = 0; info.activate = FB_ACTIVATE_NOW; /* * Request NUM_BUFFERS screens (at lest 2 for page flipping) */ info.yres_virtual = info.yres * NUM_BUFFERS; uint32_t flags = PAGE_FLIP; if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) { info.yres_virtual = info.yres; flags &= ~PAGE_FLIP; LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported"); } if (info.yres_virtual < info.yres * 2) { // we need at least 2 for page-flipping info.yres_virtual = info.yres; flags &= ~PAGE_FLIP; LOGW("page flipping not supported (yres_virtual=%d, requested=%d)", info.yres_virtual, info.yres*2); } if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) return -errno; uint64_t refreshQuotient = ( uint64_t( info.upper_margin + info.lower_margin + info.yres ) * ( info.left_margin + info.right_margin + info.xres ) * info.pixclock ); /* Beware, info.pixclock might be 0 under emulation, so avoid a * division-by-0 here (SIGFPE on ARM) */ int refreshRate = refreshQuotient > 0 ? (int)(1000000000000000LLU / refreshQuotient) : 0; if (refreshRate == 0) { // bleagh, bad info from the driver refreshRate = 60*1000; // 60 Hz } if (int(info.width) <= 0 || int(info.height) <= 0) { // the driver doesn't return that information // default to 160 dpi info.width = ((info.xres * 25.4f)/160.0f + 0.5f); info.height = ((info.yres * 25.4f)/160.0f + 0.5f); } float xdpi = (info.xres * 25.4f) / info.width; float ydpi = (info.yres * 25.4f) / info.height; float fps = refreshRate / 1000.0f; LOGI( "using (fd=%d)\n" "id = %s\n" "xres = %d px\n" "yres = %d px\n" "xres_virtual = %d px\n" "yres_virtual = %d px\n" "bpp = %d\n" "r = %2u:%u\n" "g = %2u:%u\n" "b = %2u:%u\n", fd, finfo.id, info.xres, info.yres, info.xres_virtual, info.yres_virtual, info.bits_per_pixel, info.red.offset, info.red.length, info.green.offset, info.green.length, info.blue.offset, info.blue.length ); LOGI( "width = %d mm (%f dpi)\n" "height = %d mm (%f dpi)\n" "refresh rate = %.2f Hz\n", info.width, xdpi, info.height, ydpi, fps ); if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) return -errno; if (finfo.smem_len <= 0) return -errno; module->flags = flags; module->info = info; module->finfo = finfo; module->xdpi = xdpi; module->ydpi = ydpi; module->fps = fps; /* * map the framebuffer */ int err; size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual); module->framebuffer = new private_handle_t(dup(fd), fbSize, 0); module->numBuffers = info.yres_virtual / info.yres; module->bufferMask = 0; void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (vaddr == MAP_FAILED) { LOGE("Error mapping the framebuffer (%s)", strerror(errno)); return -errno; } module->framebuffer->base = intptr_t(vaddr); memset(vaddr, 0, fbSize); return 0;}static int mapFrameBuffer(struct private_module_t* module){ pthread_mutex_lock(&module->lock); int err = mapFrameBufferLocked(module); pthread_mutex_unlock(&module->lock); return err;}/*****************************************************************************/
int gralloc_device_open(const hw_module_t* module, const char* name, hw_device_t** device){ int status = -EINVAL; if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { gralloc_context_t *dev; dev = (gralloc_context_t*)malloc(sizeof(*dev)); /* initialize our state here */ memset(dev, 0, sizeof(*dev)); /* initialize the procs */ dev->device.common.tag = HARDWARE_DEVICE_TAG; dev->device.common.version = 0; dev->device.common.module = const_cast<hw_module_t*>(module); dev->device.common.close = gralloc_close; dev->device.alloc = gralloc_alloc; dev->device.free = gralloc_free; *device = &dev->device.common; status = 0; } else { status = fb_device_open(module, name, device); } return status;}
- SurfaceFlinger调用framebuffer模块、gralloc模块流程(3)
- Android Gralloc模块分析
- GraphicBuffer和Gralloc模块
- Android SurfaceFlinger 学习之路(一)----Android图形显示之HAL层Gralloc模块实现
- GUI显示系统之SurfaceFlinger--- Gralloc与Framebuffer
- GUI系统之SurfaceFlinger(2)Gralloc与Framebuffer
- GUI系统之SurfaceFlinger(2)Gralloc与Framebuffer
- GUI系统之SurfaceFlinger(2)Gralloc与Framebuffer
- GUI显示系统之SurfaceFlinger--- Gralloc与Framebuffer
- GUI系统之SurfaceFlinger(2)Gralloc与Framebuffer
- GUI显示系统之SurfaceFlinger--- Gralloc与Framebuffer
- Android4.0 Gralloc模块学习笔记(2)
- Android HAL层分析 (gralloc显示模块 举例)
- Android Gralloc模块分析--深入分析
- Android7.0 Gralloc模块的加载
- ubuntu下启用FrameBuffer模块
- ubuntu下启用FrameBuffer模块
- Ubuntu下启用FrameBuffer模块
- DotProject 安装
- EFI Shell 命令参考
- 通过xslt将xml转换为html代码
- windows 如何查看端口占用情况?
- Canvas and Drawables
- SurfaceFlinger调用framebuffer模块、gralloc模块流程(3)
- 解决ngnix服务器上的Discuz!x2.5 Upload Error:413错误
- Android Push Notification实现信息推送使用
- 常用的ffmpeg资料
- fzu-1406
- Linux设备驱动之——I2C总线
- ORA-29701: unable to connect to Cluster Synchronization Service
- ExtJS grid中带查询参数的自动翻页控件
- hdu 2149 Public Sale