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