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;}/*****************************************************************************/


 

5:hardware/libhardware/modules/gralloc/gralloc.cpp

    

  

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;}


 

 

 

 

 

原创粉丝点击