framebuffer分析

kernel-4.4/drivers/misc/brand/video/product/videox/mtkfb.c
.compatible = "brand,MTKFB",

unsigned int lcd_fps = 6000;

mtkfb_probe

//分配物理、虛擬地址
disp_hal_allocate_framebuffer(fb_base, (fb_base + vramsize - 1),(unsigned long *)(&fbdev->fb_va_base), &fb_pa);
fbdev->fb_pa_base = fb_base;
primary_display_set_frame_buffer_address((unsigned long)(fbdev->fb_va_base), fb_pa);//pgc->framebuffer_va = fbdev->fb_va_base;pgc->framebuffer_mva = fbdev->fb_pa_base;
primary_display_init(mtkfb_find_lcm_driver(), lcd_fps, is_lcm_inited);//mtkfb_find_lcm_driver:nt35521_hd_dsi_vdo_truly_nt50358_drv

return pgc->plcm->params->physical_width;

mtkfb_fbinfo_init //填充fb_info結構體

static struct fb_ops mtkfb_ops = {
    .owner = THIS_MODULE,
    .fb_open = mtkfb_open,
    .fb_release = mtkfb_release,
    .fb_setcolreg = mtkfb_setcolreg,
    .fb_pan_display = mtkfb_pan_display_proxy,
    .fb_fillrect = cfb_fillrect,
    .fb_copyarea = cfb_copyarea,
    .fb_imageblit = cfb_imageblit,
    .fb_cursor = mtkfb_soft_cursor,
    .fb_check_var = mtkfb_check_var,
    .fb_set_par = mtkfb_set_par,
    .fb_ioctl = mtkfb_ioctl,
#ifdef CONFIG_COMPAT
    .fb_compat_ioctl = mtkfb_compat_ioctl,
#endif
#if defined(CONFIG_PM_AUTOSLEEP)
    .fb_blank = mtkfb_blank,
#endif
};

    chosen {
        bootargs = "console=tty0 console=ttyMT0,921600n1 root=/dev/ram initrd=0x44000000,\
0x1000000 loglevel=8 androidboot.selinux=permissive androidboot.hardware=product initcall_debug=1";
        /* fpga may has no lk, we need to specify display info here */
        /* fb buffer is reserved using this dts by memory node above */

        atag,videolfb-fb_base_l = <0x5e605000>;
        atag,videolfb-fb_base_h = <0>;
        atag,videolfb-islcmfound = <1>;
        atag,videolfb-islcm_inited = <0>;
        atag,videolfb-fps= <6000>;
        atag,videolfb-vramSize= <0x017bb000>;
        atag,videolfb-lcmname= "nt35521_hd_dsi_vdo_truly_nt50358_drv";
    };

drivers\misc\brand\video\product\videox\primary_display.c
primary_display_init
    disp_lcm_probe
        lcm_param = disp_lcm_get_params(pgc->plcm);
        
drivers\misc\brand\video\product\videox\disp_lcm.c
disp_lcm_probe
    plcm->drv->get_params(plcm->params);
    
kernel-4.4\drivers\misc\brand\lcm\aeon_lt8912b_fhd_dsi_vdo\aeon_lt8912b_fhd_dsi_vdo.c    
aeon_lt8912b_fhd_dsi_vdo

LCM_DRIVER aeon_lt8912b_fhd_dsi_vdo_lcm_drv = {
    .name = "aeon_lt8912b_fhd_dsi_vdo_drv",
    .set_util_funcs = lcm_set_util_funcs,
    .get_params = lcm_get_params,
    .init = lcm_init,
    .suspend = lcm_suspend,
    .resume = lcm_resume,
    .compare_id = lcm_compare_id,
    .init_power = lcm_init_power,
    .resume_power = lcm_resume_power,
    .suspend_power = lcm_suspend_power,
    .esd_check = lcm_esd_check,
    .set_backlight_cmdq = lcm_setbacklight_cmdq,
    .ata_check = lcm_ata_check,
    .update = lcm_update,
    .switch_mode = lcm_switch_mode,
};

查看dump信息
adb shell dumpsys SurfaceFlinger

createLayer
addClientLayer
mCurrentState.layersSortedByZ.add(lbc);
// attach this layer to the client
client->attachLayer(handle, lbc);

mDrawingState.layersSortedByZ
layers[i]->onPreComposition()

commitTransaction
    mDrawingState = mCurrentState;


handleMessageRefresh
    preComposition();
    rebuildLayerStacks();
    setUpHWComposer();
    doDebugFlashRegions();
    doComposition();
        doDisplayComposition
            doComposeSurfaces
                layer->draw//onDraw
                HWComposer->commit(hwcId);
                    Display->present
                    //frameworks\native\services\surfaceflinger\DisplayHardware\HWC2.cpp
                        mDevice.mPresentDisplay
                            displayPresent//vendor\brand\proprietary\hardware\hwcomposer\hwc2_api.cpp
                hwcDisplay->getReleaseFences
                    displayGetReleaseFence
    postComposition(refreshStartTime);

device/brand/product/BoardConfig.mk:84:MTK_HWC_VERSION := 2.0.0
ifneq ($(findstring 2.0, $(MTK_HWC_VERSION)),)
LOCAL_CFLAGS += -DMTK_HWC_VER_2_0
LOCAL_CFLAGS += -USE_HWC2
endif
vendor\brand\proprietary\hardware\hwcomposer\hwc2_api.cpp
hwc_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag                = HARDWARE_MODULE_TAG,
        .module_api_version = HWC_MODULE_API_VERSION_0_1,
        .hal_api_version    = HARDWARE_HAL_API_VERSION,
        .id                 = HWC_HARDWARE_MODULE_ID,
        .name               = "brand Hardware Composer HAL",
        .author             = "brand Inc.",
        .methods            = &hwc_module_methods,
        .dso                = NULL,
        .reserved           = {0},
    }
};    
    
    
截圖:
float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
// Take the screenshot
mScreenBitmap = SurfaceControl.screenshot((int) dims[0], (int) dims[1]);// width, height

nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
                false, Surface.ROTATION_0);
                
                sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj);//new Rect()
                consumer->getIGraphicBufferProducer()
                
ScreenshotClient::capture(displayToken,
                    consumer->getIGraphicBufferProducer(), sourceCrop,
                    width, height, uint32_t(minLayer), uint32_t(maxLayer),
                    useIdentityTransform);    
minLayer = 0;
maxLayer = -1;        

SurfaceFlinger::captureScreen

flinger->captureScreenImplLocked(hw, producer,
                    sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
                    useIdentityTransform, rotation, isLocalScreenshot);
                    
                    sp<Surface> sur = new Surface(producer, false);//new Rect()
                    ANativeWindow* window = sur.get();
                    //從window中拿出buffer,這個地方涉及直接的buffer了
                    native_window_dequeue_buffer_and_wait(window,  &buffer);
                    //buffer的又一種形式,轉化爲EGLImageKHR,這樣opengl系統就認得了
                    EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
                        EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
                    //綁定到繪製引擎上,你可以看成是將bitmap綁定到canvas一樣
                    //還是buffer的一種形式
                    RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
                    //開始進入繪製邏輯了,hw已經綁定了buffer
                    renderScreenImplLocked(hw, reqWidth, reqHeight,
                                minLayerZ, maxLayerZ, true);

renderScreenImplLocked(
                            hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
                            useIdentityTransform, rotation);

// set-up our viewport
    engine.setViewportAndProjection(
        reqWidth, reqHeight, sourceCrop, hw_h, yswap, rotation);
    engine.disableTexturing();

    // redraw the screen entirely...
    engine.clearWithColor(0, 0, 0, 1);

    const LayerVector& layers( mDrawingState.layersSortedByZ );
    const size_t count = layers.size();
    for (size_t i=0 ; i<count ; ++i) {
        const sp<Layer>& layer(layers[i]);
        const Layer::State& state(layer->getDrawingState());
        if (state.layerStack == hw->getLayerStack()) {
            if (state.z >= minLayerZ && state.z <= maxLayerZ) {
                if (layer->isVisible()) {
                    if (filtering) layer->setFiltering(true);
                    //核心:每個window(layer)將自己的內容繪製到buffer上
                    layer->draw(hw, useIdentityTransform);                                

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章