android graphic(11)—底层初始化displays
2016-03-08 10:01
477 查看
初始化HWC
surfaceflinger 初始化displays
这里的底层不牵扯内核以下的分析,主要是内核亮屏后,HAL层以上各层是如何联系起来的,通过层层转交,将displays的信息从内核填充到上层。这里主要涉及framework中的HWComposer,surfaceflinger,HAL层的Hwcomposer,为了便于区分,framework层记为HWC,HAL层记为Hwc,HWC相当于是Hwc的wrapper。
通过上面的步骤,主要填充了HWComposer的mDisplayDate[3]、surface flinger的mCurrentState.displays(token,DisplayDeviceState),mDisplays(token,DisplayDevice),mBuiltinDisplays[2](BBinder),
通过上面的分析,在底层,即surfaceflinger、HWC、Hwc中已经填充了系统displays的基本信息,后续分析surfaceflinger之上是如何初始化和使用displays的,上下联系起来。
surfaceflinger 初始化displays
这里的底层不牵扯内核以下的分析,主要是内核亮屏后,HAL层以上各层是如何联系起来的,通过层层转交,将displays的信息从内核填充到上层。这里主要涉及framework中的HWComposer,surfaceflinger,HAL层的Hwcomposer,为了便于区分,framework层记为HWC,HAL层记为Hwc,HWC相当于是Hwc的wrapper。
初始化HWC
SurfaceFlinger::init()—>初始化HWCmHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler) : mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false) { for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) { mLists[i] = 0; } for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) { mLastHwVSync[i] = 0; mVSyncCounts[i] = 0; } // Note: some devices may insist that the FB HAL be opened before HWC. int fberr = loadFbHalModule(); loadHwcModule(); //如果有Hwc,即HWComposer的hal层,则关闭fb if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // close FB HAL if we don't needed it. // FIXME: this is temporary until we're not forced to open FB HAL // before HWC. framebuffer_close(mFbDev); mFbDev = NULL; } // these display IDs are always reserved // NUM_BUILTIN_DISPLAYS 2 for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) { mAllocatedDisplayIDs.markBit(i); } if (mHwc) { ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER, (hwcApiVersion(mHwc) >> 24) & 0xff, (hwcApiVersion(mHwc) >> 16) & 0xff); //把HWC中,即framework中的回调函数注册到HAL中,用来在HAL中回调 if (mHwc->registerProcs) { mCBContext->hwc = this; mCBContext->procs.invalidate = &hook_invalidate; mCBContext->procs.vsync = &hook_vsync; if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) mCBContext->procs.hotplug = &hook_hotplug; else mCBContext->procs.hotplug = NULL; memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero)); mHwc->registerProcs(mHwc, &mCBContext->procs); } // don't need a vsync thread if we have a hardware composer needVSyncThread = false; // always turn vsync off when we start eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); // the number of displays we actually have depends on the // hw composer version // 1.3版本,已经支持虚拟display,3个 if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) { // 1.3 adds support for virtual displays mNumDisplays = MAX_HWC_DISPLAYS; } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) { // 1.1 adds support for multiple displays mNumDisplays = NUM_BUILTIN_DISPLAYS; } else { mNumDisplays = 1; } } //fb已经关闭 if (mFbDev) { } else if (mHwc) { // here we're guaranteed to have at least HWC 1.1 //HWC获取display信息的地方,填充mDisplayData[3] //DisplayData mDisplayData[MAX_HWC_DISPLAYS]; for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) { queryDisplayProperties(i); } } //vsync软件模拟线程 if (needVSyncThread) { // we don't have VSYNC support, we need to fake it mVSyncThread = new VSyncThread(*this); } }
//调用HAL层接口,获取屏幕的参数,HAL会和驱动打交道 //这样就相当于在上层把display的参数初始化了, //主要填充DisplayData mDisplayData[MAX_HWC_DISPLAYS]; status_t HWComposer::queryDisplayProperties(int disp) { int32_t values[NUM_DISPLAY_ATTRIBUTES - 1]; memset(values, 0, sizeof(values)); uint32_t config; size_t numConfigs = 1; status_t err = mHwc->getDisplayConfigs(mHwc, disp, &config, &numConfigs); err = mHwc->getDisplayAttributes(mHwc, disp, config, DISPLAY_ATTRIBUTES, values); int32_t w = 0, h = 0; for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { switch (DISPLAY_ATTRIBUTES[i]) { case HWC_DISPLAY_VSYNC_PERIOD: mDisplayData[disp].refresh = nsecs_t(values[i]); break; case HWC_DISPLAY_WIDTH: mDisplayData[disp].width = values[i]; break; case HWC_DISPLAY_HEIGHT: mDisplayData[disp].height = values[i]; break; case HWC_DISPLAY_DPI_X: mDisplayData[disp].xdpi = values[i] / 1000.0f; break; case HWC_DISPLAY_DPI_Y: mDisplayData[disp].ydpi = values[i] / 1000.0f; break; default: ALOG_ASSERT(false, "unknown display attribute[%d] %#x", i, DISPLAY_ATTRIBUTES[i]); break; } } // FIXME: what should we set the format to? mDisplayData[disp].format = HAL_PIXEL_FORMAT_RGBA_8888; mDisplayData[disp].connected = true; if (mDisplayData[disp].xdpi == 0.0f || mDisplayData[disp].ydpi == 0.0f) { float dpi = getDefaultDensity(h); mDisplayData[disp].xdpi = dpi; mDisplayData[disp].ydpi = dpi; } return NO_ERROR; }
surfaceflinger 初始化displays
SurfaceFlinger::init()—>// initialize our non-virtual displays // 初始化物理屏幕,NUM_BUILTIN_DISPLAY_TYPES 2 // 目前除了默认屏幕,还支持一个hdmi的物理屏幕 for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) { DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i); // set-up the displays that are already connected // 屏幕是否连接,即HWC中已经成功获取到这个屏幕的信息 if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) { // All non-virtual displays are currently considered secure. bool isSecure = true; // 创建显示器在surface flinger中的代表,new BBinder, // 将new BBinder和DisplayDeviceState保存在mCurrentState.displays中 createBuiltinDisplayLocked(type); //取出上面的BBinder wp<IBinder> token = mBuiltinDisplays[i]; //新建BufferQueue,FramebufferSurface,DisplayDevice sp<BufferQueue> bq = new BufferQueue(new GraphicBufferAlloc()); sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, bq); sp<DisplayDevice> hw = new DisplayDevice(this, type, allocateHwcDisplayId(type), isSecure, token, fbs, bq, mEGLConfig); if (i > DisplayDevice::DISPLAY_PRIMARY) { // FIXME: currently we don't get blank/unblank requests // for displays other than the main display, so we always // assume a connected display is unblanked. ALOGD("marking display %d as acquired/unblanked", i); hw->acquireScreen(); } // DefaultKeyedVector< wp<IBinder>, sp<DisplayDevice> > mDisplays; mDisplays.add(token, hw); } }
bool HWComposer::isConnected(int disp) const { return mDisplayData[disp].connected; }
struct State { LayerVector layersSortedByZ; DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays; }; struct DisplayDeviceState { DisplayDeviceState(); DisplayDeviceState(DisplayDevice::DisplayType type); bool isValid() const { return type >= 0; } bool isMainDisplay() const { return type == DisplayDevice::DISPLAY_PRIMARY; } bool isVirtualDisplay() const { return type >= DisplayDevice::DISPLAY_VIRTUAL; } DisplayDevice::DisplayType type; sp<IGraphicBufferProducer> surface; uint32_t layerStack; Rect viewport; Rect frame; uint8_t orientation; String8 displayName; bool isSecure; }; void SurfaceFlinger::createBuiltinDisplayLocked(DisplayDevice::DisplayType type) { ALOGW_IF(mBuiltinDisplays[type], "Overwriting display token for display type %d", type); //sp<IBinder> mBuiltinDisplays[2]; 就是new BBinder, mBuiltinDisplays[type] = new BBinder(); DisplayDeviceState info(type); // All non-virtual displays are currently considered secure. // 非virtual display都是secure的 info.isSecure = true; // State mCurrentState; mCurrentState.displays.add(mBuiltinDisplays[type], info); }
SurfaceFlinger::DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type) : type(type), layerStack(DisplayDevice::NO_LAYER_STACK), orientation(0) { viewport.makeInvalid(); frame.makeInvalid(); }
通过上面的步骤,主要填充了HWComposer的mDisplayDate[3]、surface flinger的mCurrentState.displays(token,DisplayDeviceState),mDisplays(token,DisplayDevice),mBuiltinDisplays[2](BBinder),
// initialize our drawing state mDrawingState = mCurrentState; // set initial conditions (e.g. unblank default device) initializeDisplays();
void SurfaceFlinger::initializeDisplays() { class MessageScreenInitialized : public MessageBase { SurfaceFlinger* flinger; public: MessageScreenInitialized(SurfaceFlinger* flinger) : flinger(flinger) { } virtual bool handler() { flinger->onInitializeDisplays(); return true; } }; sp<MessageBase> msg = new MessageScreenInitialized(this); postMessageAsync(msg); // we may be called from main thread, use async message }
void SurfaceFlinger::onInitializeDisplays() { // reset screen orientation and use primary layer stack Vector<ComposerState> state; Vector<DisplayState> displays; //新建一个DisplayState DisplayState d; d.what = DisplayState::eDisplayProjectionChanged | DisplayState::eLayerStackChanged; //默认屏幕的token d.token = mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]; //layerStack 为0,orientation 为默认的eOrientationDefault d.layerStack = 0; d.orientation = DisplayState::eOrientationDefault; d.frame.makeInvalid(); d.viewport.makeInvalid(); displays.add(d); //利用displays的信息,设置mCurrentState.displays的状态 setTransactionState(state, displays, 0); onScreenAcquired(getDefaultDisplayDevice()); const nsecs_t period = getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); mAnimFrameTracker.setDisplayRefreshPeriod(period); }
void SurfaceFlinger::setTransactionState( const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags) { ATRACE_CALL(); Mutex::Autolock _l(mStateLock); uint32_t transactionFlags = 0; size_t count = displays.size(); for (size_t i=0 ; i<count ; i++) { const DisplayState& s(displays[i]); transactionFlags |= setDisplayStateLocked(s); } }
//根据DisplayState的信息更新mCurrentState.displays的信息 uint32_t SurfaceFlinger::setDisplayStateLocked(const DisplayState& s) { ssize_t dpyIdx = mCurrentState.displays.indexOfKey(s.token); if (dpyIdx < 0) return 0; uint32_t flags = 0; DisplayDeviceState& disp(mCurrentState.displays.editValueAt(dpyIdx)); if (disp.isValid()) { const uint32_t what = s.what; if (what & DisplayState::eSurfaceChanged) { if (disp.surface->asBinder() != s.surface->asBinder()) { disp.surface = s.surface; flags |= eDisplayTransactionNeeded; } } if (what & DisplayState::eLayerStackChanged) { if (disp.layerStack != s.layerStack) { disp.layerStack = s.layerStack; flags |= eDisplayTransactionNeeded; } } if (what & DisplayState::eDisplayProjectionChanged) { if (disp.orientation != s.orientation) { disp.orientation = s.orientation; flags |= eDisplayTransactionNeeded; } if (disp.frame != s.frame) { disp.frame = s.frame; flags |= eDisplayTransactionNeeded; } if (disp.viewport != s.viewport) { disp.viewport = s.viewport; flags |= eDisplayTransactionNeeded; } } } return flags; }
// returns the default Display // 返回默认屏幕的DisplayDevice sp<const DisplayDevice> getDefaultDisplayDevice() const { return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]); } sp<DisplayDevice> getDisplayDevice(const wp<IBinder>& dpy) { return mDisplays.valueFor(dpy); }
void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) { ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this); if (hw->isScreenAcquired()) { // this is expected, e.g. when power manager wakes up during boot ALOGD(" screen was previously acquired"); return; } hw->acquireScreen(); int32_t type = hw->getDisplayType(); if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { // built-in display, tell the HWC getHwComposer().acquire(type); if (type == DisplayDevice::DISPLAY_PRIMARY) { // FIXME: eventthread only knows about the main display right now mEventThread->onScreenAcquired(); //开启vsync开关 resyncToHardwareVsync(true); } } mVisibleRegionsDirty = true; repaintEverything(); }
void DisplayDevice::acquireScreen() const { mScreenAcquired = true; }
//acquire就是调用Hwc HAL的blank函数, status_t HWComposer::acquire(int disp) { LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE); if (mHwc) { return (status_t)mHwc->blank(mHwc, disp, 0); } return NO_ERROR; }
通过上面的分析,在底层,即surfaceflinger、HWC、Hwc中已经填充了系统displays的基本信息,后续分析surfaceflinger之上是如何初始化和使用displays的,上下联系起来。
相关文章推荐
- Android Studio Error:Plugin is too old, please update to a more recent version
- andorid动态布局
- android获得屏幕宽高和控件宽高
- android检测某一个线程是否开启
- Android Support库百分比布局
- ImageCoverFlow
- Android SQLite数据库升级
- Android系统在新进程中启动自定义服务过程(startService)的原理分析
- Android ProGuard 混淆 详解
- android开发技巧——仿新版QQ锁屏下弹窗
- android获取路径
- Android 5.0新特性了解(一)----TabLayout
- android开发过程中的log日志管理
- Kotlin(2): 优雅地扩展类的方法和属性
- 4.10 Android VideoView播放视频
- Android应用第一次安装成功点击“打开”后Home键切出应用后再点击桌面图标返回导致应用重启问题
- Android中使用TabHost 与 Fragment 制作页面切换效果
- Vectors(2): 绘制优美的路径动画
- Android多进程编程 IPC(Inter-Process Communiction) 小摘
- 《Android开发艺术探索》15章Android性能优化