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中的接口

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

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

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的构造函数中赋值
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8


4:看下SF中的onHotplugReceived()

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信号来临的时候去创建新的显示设备
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

5:业务处理

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

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

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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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

//在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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

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

相关文章
相关标签/搜索