surfaceflinger增加hdmi显示设备

转载地址:http://blog.csdn.net/u010865783/article/category/6677819

1:当hdmi插入的时候,hdmi驱动会上报一个中断上来,在驱动中会发送一个Uevent给上层。 
“/sys/class/switch/hdmi/state” 这个节点会由0变成1

2:在HWC中,启动的时候就开启一个hdmi状态监听的线程,当这个节点有变化的时候,会去设置hdmi分辨率,打开hdmi设备,而且还更新自己的节点状态。

根据上面的hdmi使能之后,调用到: 
HWC_OWL_ContextHotplugDisplay()来更新hdmi的状态,主要是向上层报告增加了一个hdmi设备。 
代码如下: 
//这里会回调到HWComposer中的接口

 
 
  • 1
  • 2
  • 3
  • 4
pthread_mutex_lock(&psPrivateData->sHdmiMutexLock); psHwcFuncs->pfnContextHotplugDisplay(psPrivateData,eDisplay, bConnected); pthread_mutex_unlock(&psPrivateData->sHdmiMutexLock); psPrivateData->psHwcProcs->hotplug(psPrivateData->psHwcProcs, iDisplay, iConnected);

3:回到HWComposer中,来看下hotplug接口:

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
void HWComposer::hotplug(int disp, int connected) { if (disp == HWC_DISPLAY_PRIMARY || disp >= VIRTUAL_DISPLAY_ID_BASE) { ALOGE("hotplug event received for invalid display: disp=%d connected=%d", disp, connected); return; } queryDisplayProperties(disp); //得到显示设备的配置信息,比如分辨率 density等信息 mEventHandler.onHotplugReceived(disp, bool(connected)); //注意这个mEventHandler其实就是surfaceflinger对象,在HWC的构造函数中赋值


4:看下SF中的onHotplugReceived()

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
void SurfaceFlinger::onHotplugReceived(int type, bool connected) { if (uint32_t(type) < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { Mutex::Autolock _l(mStateLock); if (connected) { //将HDMI设备加入到全局的display列表中 createBuiltinDisplayLocked((DisplayDevice::DisplayType)type); } else { mCurrentState.displays.removeItem(mBuiltinDisplays[type]); mBuiltinDisplays[type].clear(); } setTransactionFlags(eDisplayTransactionNeeded);//设置transactionFlags为eDisplayTransactionNeeded 这个变量会在下一个vsync信号来临的时候去创建新的显示设备 }

5:业务处理

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
SurfaceFlinger::handleTransactionLocked()中, for (size_t i=0 ; i<cc ; i++) { //1:创建createBufferQueue BufferQueue::createBufferQueue(&bqProducer, &bqConsumer, new GraphicBufferAlloc()); hwcDisplayId = allocateHwcDisplayId(state.type); dispSurface = new FramebufferSurface(*mHwc, state.type, bqConsumer); producer = bqProducer; } const wp<IBinder>& display(curr.keyAt(i)); if (dispSurface != NULL) { //2:创建DisplayDevice sp<DisplayDevice> hw = new DisplayDevice(this, state.type, hwcDisplayId, mHwc->getFormat(hwcDisplayId), state.isSecure, display, dispSurface, producer, mRenderEngine->getEGLConfig()); hw->setLayerStack(state.layerStack); hw->setProjection(state.orientation, state.viewport, state.frame); hw->setDisplayName(state.displayName); mDisplays.add(display, hw); //唤醒vsync线程 mEventThread->onHotplugReceived(state.type, true); } } } } } }

6:在EventThread中看下这个onHotplugReceived函数:

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
void EventThread::onHotplugReceived(int type, bool connected) { ALOGE_IF(type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES, "received hotplug event for an invalid display (id=%d)", type); Mutex::Autolock _l(mLock); if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) { DisplayEventReceiver::Event event; //这里设置的type为DISPLAY_EVENT_HOTPLUG event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG; event.header.id = type; event.header.timestamp = systemTime(); event.hotplug.connected = connected; mPendingEvents.add(event); //唤醒vsync线程 mCondition.broadcast(); } }

6:在EventThread::threadLoop()中将上面的消息通过BitTube发送出去

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
//在onHotplugReceived中已经把它唤醒 signalConnections = waitForEvent(&event); // dispatch events to listeners... const size_t count = signalConnections.size(); for (size_t i=0 ; i<count ; i++) { const sp<Connection>& conn(signalConnections[i]); // now see if we still need to report this event //将event事件发送出去 status_t err = conn->postEvent(event); //具体postEvent的实现 status_t EventThread::Connection::postEvent( const DisplayEventReceiver::Event& event) { ssize_t size = DisplayEventReceiver::sendEvents(mChannel, &event, 1); return size < 0 ? status_t(size) : status_t(NO_ERROR); } //sendEvents的实现 ssize_t DisplayEventReceiver::sendEvents(const sp<BitTube>& dataChannel, Event const* events, size_t count) { return BitTube::sendObjects(dataChannel, events, count); }

上层接收Vsync和DISPLAY_EVENT_HOTPLUG事件的接收者是:NativeDisplayEventReceiver 
会直接调用它的方法:NativeDisplayEventReceiver::handleEvent方法; 
具体接收流程在另外一篇文章中做了详细说明:http://blog.csdn.net/u010865783/article/details/54616739  这篇文章是对那篇文章底层hdmi插拔事件的一个补充。

相关文章
相关标签/搜索