硬件显示设备

在HWC 1.1之前,没有支持HWC_FRAMEBUFFER_TARGET,HWC从当前线程上下文中获取GLES的Display和Surface。
在所有层都由HWC合成时,不需要GLES,HWC_FRAMEBUFFER_TARGET层数据没有意义。
虚拟显示设备

当虚拟显示设备得不到HWC支持时(HWC 1.3以前,或者虚拟设备数超限),SurfaceFlinger安排GLES直接合成到输出Surface(图中绿色线指示的流)。
VirtualDisplaySurface虚拟了一个BufferQueue(实现IGraphicBufferProducer接口),根据情况可能从中间BufferQueue或者目标BufferQueue获取缓存提供给GLES做合成,具体策略是:如果HWC返回全部由GLES合成时,从目标BufferQueue获取缓存。
流程
下面这个文章里面有SurfaceFlinger调用OpenGL的堆栈,同时问题就出在OpenGL、Overlay合成分工上。
线程
SurfaceFlinger:
| 名称 | 入口 | 说明 |
| main | MessageQueue:: waitMessage() | init、run,SurfaceFlinger内部线程,invalidate、refresh消息,vsync信号 |
| Binder_%X | IPCThreadState:: joinThreadPool | 4个线程 |
| EventControl | EventControlThread:: threadLoop() | 控制硬件vsync开关 |
| EventThread | EventThread:: threadLoop() | 分发vsync信号,BitTube,2个线程,一个内部,一个App |
| DispSync | DispSyncThread:: threadLoop() | 产生软件vsync信号 |
SystemServer:
| 名称 | 入口 | 说明 |
| WindowManager | Looper.loop() | SystemServer 创建的wmHandlerThread, DisplayManagerHandler、DisplayAdapter |
| android.ui | Looper.loop() | mUiHandler |
初始化
SurfaceFlinger在init方法中进行初始化。
- 初始化EGL
- eglGetDisplay
- eglInitialize
- new HWComposer
- RenderEngine::create
- 初始化内建显示设备
- for i = 0 ~ NUM_BUILTIN_DISPLAY_TYPES
- new BufferQueue
- new FramebufferSurface
- new DisplayDevice
- mDisplays.add
- 初始化辅助线程,消息队列
- new DispSyncSource
- new EventThread
- new DispSyncSource
- new EventThread
- mEventQueue.setEventThread
- new EventControlThread
- 其他
- initializeDisplays
- postMessageAsync(MessageScreenInitialized)
- startBootAnim
VSync信号
- HWComposer收到VSync回调(HWComposer::vsync)
- HWComposer::vsync
- mEventHandler.onVSyncReceived(EventHandler接口,由SurfaceFlinger实现)
- SurfaceFlinger处理VSync回调(SurfaceFlinger::onVSyncReceived)
- SurfaceFlinger::onVSyncReceived
- if (type == 0 && mPrimaryHWVsyncEnabled)(type实际是Display id,只处理主屏幕的vsync)
- needsHwVsync = mPrimaryDispSync.addResyncSample(送到DispSync)
- if (needsHwVsync)
- enableHardwareVsync
- else
- disableHardwareVsync
- if (type == 0 && mPrimaryHWVsyncEnabled)(type实际是Display id,只处理主屏幕的vsync)
- DispSync计算VSync统计变量(DispSync::addResyncSample)
DispSync需要同步硬件Vsync,通过beginResync、addResyncSample、endResync做一次重新同步。addResyncSample需要多次调用知道返回false表示同步完成。
- DispSync::addResyncSample
- 添加当前Vsync时间戳到循环数组,只记录最近若干采样
- updateModelLocked
- 计算周期(mPeriod)和偏移(mPhase),偏移相对于时间0开始的周期信号
- mThread->updateModel(更新到内部线程DispSyncThread)
- DispSyncThread产生软件VSync信号(DispSyncThread::threadLoop)
DispSyncThread为多个客户端(Listener)产生不同偏移(相对于硬件Vsync)的周期信号。
- DispSyncThread::threadLoop
- computeNextEventTimeLocked
- foreach mEventListeners(计算每个Listener的下一个信号时间)
- computeListenerNextEventTimeLocked
- 下一个时间0开始的周期信号加上硬件偏移和客户端指定偏移
- 取最小值
- computeListenerNextEventTimeLocked
- foreach mEventListeners(计算每个Listener的下一个信号时间)
- mCond.waitRelative(等待到下一个信号时间)
- gatherCallbackInvocationsLocked(收集到期的信号回调)
- fireCallbackInvocations(调用回调,DispSync::Callback接口,由DispSyncSource实现)
- computeNextEventTimeLocked
- DispSyncSource将软件VSync发送给注册的回调(DispSyncSource::onDispSyncEvent)
DispSyncSource纯粹是为了接口转换,可能是兼容的原因。
- DispSyncSource::onDispSyncEvent
- callback->onVSyncEvent(VSyncSource::Callback接口,由EventThread实现)
- EventThread记录VSync信号,转换为内部事件
- EventThread::onVSyncEvent
- mVSyncEvent[0].vsync.count++(DisplayEventReceiver::Event类型)
- mCondition.broadcast(唤醒内部线程
- EventThread内部线程将软件VSync发送给注册客户端(EventThread::threadLoop)
- EventThread::threadLoop
- waitForEvent(等待事件,并返回感兴趣的连接EventThread::Connection)
- foreach mVSyncEvent(数组只有第一个可能会有Vsync事件)
- if (event.header.timestamp)
- foreach mDisplayEventConnections(所有连接)
- 根据connection->count(0,接收一次,变为-1,>0,如果整除,接收)
- foreach mVSyncEvent(数组只有第一个可能会有Vsync事件)
- foreach signalConnections
- conn->postEvent(event)
- DisplayEventReceiver::sendEvents
- BitTube::sendObjects(通过BitTube管道发送事件)
- DisplayEventReceiver::sendEvents
- conn->postEvent(event)
- waitForEvent(等待事件,并返回感兴趣的连接EventThread::Connection)
- MessageQueue接收事件(MessageQueue::cb_eventReceiver)
MessageQueue在内部线程(Looper)注册BitTube句柄,当句柄上有数据时,调用注册的回调cb_eventReceiver。
- MessageQueue::cb_eventReceiver
- queue->eventReceiver
- while (DisplayEventReceiver::getEvents)(从BitTube管道读取事件)
- if (buffer[i].header.type == DISPLAY_EVENT_VSYNC)
- #if INVALIDATE_ON_VSYNC
- mHandler->dispatchInvalidate();
- mQueue.mLooper->sendMessage(发送消息)
- mHandler->dispatchInvalidate();
- #else
- mHandler->dispatchRefresh();
- mQueue.mLooper->sendMessage(发送消息)
- mHandler->dispatchRefresh();
- #endif
- #if INVALIDATE_ON_VSYNC
- if (buffer[i].header.type == DISPLAY_EVENT_VSYNC)
- while (DisplayEventReceiver::getEvents)(从BitTube管道读取事件)
- queue->eventReceiver
- MessageQueue处理消息(MessageQueue::Handler::handleMessage)
- MessageQueue::Handler::handleMessage
- mQueue.mFlinger->onMessageReceived(SurfaceFlinger处理消息,详见下文)
增加虚拟屏幕
- 应用层调用方式(TODO:示例源代码)
- new SurfaceComposerClient(创建到SurfaceFlinger的客户端连接)
- createDisplay(创建虚拟屏幕)
- Composer::getInstance().createDisplay
- ComposerService::getComposerService()->createDisplay
- Composer::getInstance().createDisplay
- openGlobalTransaction(打开一个事务)
- Composer::openGlobalTransaction
- setDisplaySurface(设置虚拟屏幕表面Surface)
- Composer::getInstance().setDisplaySurface
- setDisplayLayerStack(设备虚拟屏幕图层镜像)
- Composer::getInstance().setDisplayLayerStack
- setDisplayProjection(设备虚拟屏幕投影区域)
- Composer::getInstance().setDisplayProjection
- closeGlobalTransaction(提交事务)
- Composer::closeGlobalTransaction
- Composer::getInstance().closeGlobalTransactionImpl
- sm->setTransactionState
- Composer::getInstance().closeGlobalTransactionImpl
- Composer::closeGlobalTransaction
- SurfaceFlinger创建虚拟屏幕(SurfaceFlinger::createDisplay)
- SurfaceFlinger::createDisplay
- new DisplayToken(Binder对象,用来自动释放)
- DisplayDeviceState(DisplayDevice::DISPLAY_VIRTUAL)
- mCurrentState.displays.add(添加到读取状态,后面与事务一起处理)
- SurfaceFlinger处理客户端事务(SurfaceFlinger::setTransactionState)
- SurfaceFlinger::setTransactionState
- foreach displays(外部更新状态)
- setDisplayStateLocked
- mCurrentState.displays.indexOfKey(查找内部数组对应屏幕)
- if (what & DisplayState::eSurfaceChanged)(屏幕表面变化)
- flags |= eDisplayTransactionNeeded
- if (what & DisplayState::eLayerStackChanged)(图层栈变化)
- flags |= eDisplayTransactionNeeded
- setDisplayStateLocked
- if (transactionFlags)
- setTransactionFlags
- signalTransaction
- mEventQueue.invalidate(排队Invalidate消息)
- signalTransaction
- setTransactionFlags
- foreach displays(外部更新状态)
- SurfaceFlinger处理增加虚拟屏幕事务(SurfaceFlinger:: handleMessageTransaction)
Invalidate消息处理,包含事务处理(handleMessageTransaction,详见“事务处理”),这里列举增加虚拟屏幕相关的部分。
- SurfaceFlinger::handleMessageTransaction
- handleTransactionLocked
- if (transactionFlags & eDisplayTransactionNeeded)
- 比较mCurrentState和mDrawingState,对增加的屏幕
- if (DisplayDeviceState::isVirtualDisplay)
- allocateHwcDisplayId(申请硬件虚拟屏幕ID,可能失败)
- new BufferQueue(GLES合成的表面)
- new VirtualDisplaySurface
- new DisplayDevice
- if (DisplayDeviceState::isVirtualDisplay)
- 比较mCurrentState和mDrawingState,对增加的屏幕
- if (transactionFlags & eDisplayTransactionNeeded)
- handleTransactionLocked
连接WifiDisplay
- DisplayManager启动连接Wifi设备(connectWifiDisplay)
- DisplayManagerGlobal.connectWifiDisplay()
- mDm.connectWifiDisplay()【DisplayManagerService】
- mWifiDisplayAdapter.requestConnectLocked()
- mDisplayController.requestConnect()
- connect()
- updateConnection()
- connect()
- mDisplayController.requestConnect()
- mWifiDisplayAdapter.requestConnectLocked()
- mDm.connectWifiDisplay()【DisplayManagerService】
- WifiDisplayController更新连接状态(updateConnection)
- 关闭老的设备连接【略过】
- new WifiP2pConfig()
- new WpsInfo()
- createWifiDisplay()
- advertiseDisplay()【清空老的记录】
- mWifiP2pManager.connect()【Wifi P2P连接】
- 等待WIFI_P2P_CONNECTION_CHANGED_ACTION
- WifiDisplayController处理P2p连接变化广播(mWifiP2pReceiver)
- mWifiP2pReceiver.onReceive()
- handleConnectionChanged()
- mWifiP2pManager.requestGroupInfo()【等待回调】
- handleConnectionChanged()
- GroupInfoListener.onGroupInfoAvailable()【requestGroupInfo回调】
- updateConnection()【根据当前状态,应该到第6步】
- mWifiP2pManager.setMiracastMode()
- RemoteDisplay.listen()【侦听远端设备RTSP连接】
- updateConnection()【根据当前状态,应该到第6步】
- RemoteDisplay启动侦听
- RemoteDisplay.listen()
- new RemoteDisplay()
- display.startListening
- nativeListen()【JNI】
- IServiceManager->getService()【IMediaPlayerService,"media.player"】
- new NativeRemoteDisplayClient【IRemoteDisplayClient】
- IMediaPlayerService->listenForRemoteDisplay()【返回IRemoteDisplay】
- new NativeRemoteDisplay()【包装IRemoteDisplay】
- nativeListen()【JNI】
- RemoteDisplay收到连接
- NativeRemoteDisplayClient::onDisplayConnected(IGraphicBufferProducer)
- android_view_Surface_createFromIGraphicBufferProducer()
- new Surface()【提供数据方】
- RemoteDisplay.notifyDisplayConnected()【从JNI回调】
- mHandler.post(mListener.onDisplayConnected())【Handler线程调用回调】
- android_view_Surface_createFromIGraphicBufferProducer()
- WifiDisplayController处理成功消息
- RemoteDisplay.Listener.onDisplayConnected()
- mListener.onDisplaySessionInfo()【WifiDisplayAdapter】
- mWifiDisplayListener.onDisplaySessionInfo()
- createWifiDisplay()
- advertiseDisplay()
- mHandler.post()【Handler线程post onDisplayConnected】
- mListener.onDisplaySessionInfo()【WifiDisplayAdapter】
- WifiDisplayAdapter处理成功消息
- mListener.onDisplayConnected()
- mWifiDisplayListener.onDisplayConnected()
- addDisplayDeviceLocked()
- new WifiDisplayDevice()
- sendDisplayDeviceEventLocked()
- mHandler.post()【mListener.onDisplayDeviceEvent(),通知到DisplayManagerService】
- scheduleStatusChangedBroadcastLocked()【异步发送广播DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED】
- scheduleUpdateNotificationLocked()【异步更新通知栏UI】
- addDisplayDeviceLocked()
- mWifiDisplayListener.onDisplayConnected()
- DisplayManagerService处理成功消息
- DisplayAdapterListener.onDisplayDeviceEvent()
- DisplayManagerService.handleDisplayDeviceAdded()
- handleDisplayDeviceAddedLocked()
- mDisplayDevices.add()
- addLogicalDisplayLocked()
- new LogicalDisplay()
- mLogicalDisplays.put()
- sendDisplayEventLocked()【异步回调IDisplayManagerCallback.notifyDisplayEventAsync(),DisplayManagerGlobal.EVENT_DISPLAY_ADDED】
- updateDisplayBlankingLocked()【与PowerManager屏幕状态一致】
- scheduleTraversalLocked()【异步请求mWindowManagerFuncs.requestTraversal()】
- handleDisplayDeviceAddedLocked()
- DisplayManagerService.handleDisplayDeviceAdded()
- DisplayManagerService处理更新事务
- performTraversalInTransactionFromWindowManager()
- performTraversalInTransactionLocked()
- handleDisplayDeviceAddedLocked()
- foreach device : mDisplayDevices
- configureDisplayInTransactionLocked()
- findLogicalDisplayForDeviceLocked()
- display.configureDisplayInTransactionLocked()
- device.setLayerStackInTransactionLocked()
- device.setProjectionInTransactionLocked()
- device.performTraversalInTransactionLocked()
- setSurfaceInTransactionLocked()【WifiDisplayDevice】
- configureDisplayInTransactionLocked()
- performTraversalInTransactionLocked()
消息处理
SurfaceFlinger在onMessageReceived中处理消息,调用线程是MessageQueue线程。
在处理TRANSACTION消息时,需要做事务处理。
在处理INVALIDATE消息时,先做事务处理,然后更新失效区域,最后在MessageQueue中安排一个REFRESH消息。
在处理REFRESH消息时,做屏幕刷新。
事务处理(Transaction)
- SurfaceFlinger在handleMessageTransaction中处理事务
- handleMessageTransaction
- handleTransaction(transactionFlags)
- handleTransactionLocked(具体的事务处理)
- invalidateHwcGeometry()
- mHwWorkListDirty = true
- handleTransaction(transactionFlags)
- 具体的事务处理过程
- handleTransactionLocked
- if (transactionFlags & eTraversalNeeded)(这里只处理layer内部的事务)
- if (transactionFlags & eDisplayTransactionNeeded)(处理设备插拔事务)
- if (transactionFlags & eTraversalNeeded| eDisplayTransactionNeeded)(更新layer到Display的角度转换)
- if (mLayersRemoved)(处理layer删除)
- commitTransaction(提交事务完成)
- layer内部事务处理过程
- foreach mCurrentState.layersSortedByZ
- if (!layer->getTransactionFlags) continue(该layer没有事务)
- layer->doTransaction(返回变化的状态,记录可见区域变化)
- 设备插拔事务处理过程
- foreach mDrawingState.displays
- 如果mCurrentState.displays没有对应的(删除)
- DisplayDevice::disconnect(hwc)
- mEventThread->onHotplugReceived
- 如果有对应的(保留)
- Surface变化
- 删除(稍后会添加),continue
- DisplayDevice::setLayerStack(layerStack变化)
- DisplayDevice::setProjection(orientation、viewport、frame变化)
- Surface变化
- 如果mCurrentState.displays没有对应的(删除)
- foreach mCurrentState.displays
- 如果mDrawingState.displays没有对应的(增加)
- if (DisplayDeviceState::isVirtualDisplay)
- allocateHwcDisplayId
- new BufferQueue(new GraphicBufferAlloc())
- new VirtualDisplaySurface
- else
- allocateHwcDisplayId
- new FramebufferSurface
- new DisplayDevice
- mEventThread->onHotplugReceived
- if (DisplayDeviceState::isVirtualDisplay)
- 如果mDrawingState.displays没有对应的(增加)
- 更新layer到Display的角度转换
- foreach mCurrentState.layersSortedByZ
- 如果layerStack变化(因为先根据layerStack排序,可以减少查找次数)
- 查找对应的Display,没有一一对应关系,使用默认Display
- layer->updateTransformHint(disp)
- 如果layerStack变化(因为先根据layerStack排序,可以减少查找次数)
- 处理layer删除
- foreach mDrawingState.layersSortedByZ
- 如果mCurrentState.layersSortedByZ没有对应的(删除)
- invalidateLayerStack
- 如果mCurrentState.layersSortedByZ没有对应的(删除)
- 提交事务完成
- foreach mLayersPendingRemoval
- layer->onRemoved
- mDrawingState = mCurrentState
失效更新(Invalidate)
- SurfaceFlinger在handleMessageInvalidate中处理失效更新
- handleMessageInvalidate
- handlePageFlip
- foreach layers
- layer->latchBuffer(锁住当前缓存,返回失效区域,还返回是否需要重新计算可见区域)
- layer->getDrawingState
- invalidateLayerStack(更新显示设备的失效区域)
- mVisibleRegionsDirty|= visibleRegions(可见区域失效)
- foreach layers
- handlePageFlip
- layer锁住当前缓存
- Layer::latchBuffer
- SurfaceFlingerConsumer::updateTexImage
- 如果上面返回BufferQueue::PRESENT_LATER
- SurfaceFlinger::signalLayerUpdate(再次安排更新任务)
- 返回空区域
- if (--mQueuedFrames)(多个排队缓存)
- SurfaceFlinger::signalLayerUpdate(再次安排更新任务)
- SurfaceFlingerConsumer::getCurrentBuffer
- 如果crop、transform、scalingMode,bufWidth、bufHeight、Opacity变化了
- recomputeVisibleRegions = true(需要重新计算可见区域)
- s.active.w、s.active.h、s.transform计算出outDirtyRegion(这里只是简单使用整个区域)
- 更新显示设备的失效区域
- invalidateLayerStack
- 根据layerStack查找mDisplays
- hw->dirtyRegion.orSelf(dirty)
屏幕刷新(Refresh)
- SurfaceFlinger在handleMessageRefresh中处理屏幕刷新
- handleMessageRefresh
- preComposition(预处理)
- rebuildLayerStacks(重构Layer栈)
- setUpHWComposer(构建硬件合成工作序列)
- doDebugFlashRegions
- doComposition(合成layers)
- postComposition(合成后处理)
- 预处理(preComposition)
- preComposition
- foreach mDrawingState.layersSortedByZ
- if (layer->onPreComposition)(如果有等待的缓存,返回true)
- needExtraInvalidate = true
- if (layer->onPreComposition)(如果有等待的缓存,返回true)
- if (needExtraInvalidate)
- signalLayerUpdate(排队新的更新消息)
- foreach mDrawingState.layersSortedByZ
- 重构Layer栈(rebuildLayerStacks)
- rebuildLayerStacks(mVisibleRegionsDirty为真时有用)
- invalidateHwcGeometry(设置几何拓扑失效标志)
- foreach mDisplays
- computeVisibleRegions(计算各个layer的失效区域,透明区域等等)
- 构建硬件合成工作序列(setUpHWComposer)
- setUpHWComposer
- foreach mDisplays
- hw->beginFrame
- mDisplaySurface->beginFrame(HWC prepare前调用)
- hw->beginFrame
- if (mHwWorkListDirty)(几何拓扑失效,在事务处理时或者可见区域变化时设置)
- foreach mDisplays
- hwc.createWorkList(创建hwc_display_contents_1)
- foreach mDisplays
- foreach mDisplays
- foreach mVisibleLayersSortedByZ
- layer->setPerFrameData(传递图像缓存到HWC图层)
- hwcLayer.setBuffer
- layer->setPerFrameData(传递图像缓存到HWC图层)
- foreach mVisibleLayersSortedByZ
- hwc.prepare
- foreach mDisplays
- hw->prepareFrame
- mDisplaySurface->prepareFrame(HWC prepare后调用)
- hw->prepareFrame
- foreach mDisplays
- 合成layers(doComposition)
- doComposition
- foreach mDisplays
- doDisplayComposition(创建hwc_display_contents_1)
- doComposeSurfaces
- getRenderEngine
- if (hasGlesComposition)
- hw->makeCurrent
- if (hasHwcComposition)
- engine.clearWithColor
- else
- drawWormhole
- engine.fillRegionWithColor
- drawWormhole
- if (cur != end)(使用HWC)
- foreach mVisibleLayersSortedByZ
- switch (cur->getCompositionType())
- case HWC_OVERLAY
- layer->clearWithOpenGL
- case HWC_FRAMEBUFFER
- layer->draw
- case HWC_OVERLAY
- layer->setAcquireFence(传递同步Fence到HWC)
- mSurfaceFlingerConsumer->getCurrentFence
- hwlayer.setAcquireFenceFd
- switch (cur->getCompositionType())
- foreach mVisibleLayersSortedByZ
- else(没有使用HWC)
- foreach mVisibleLayersSortedByZ
- layer->draw
- foreach mVisibleLayersSortedByZ
- hw->swapBuffers
- eglSwapBuffers(如果没有HWC,或者hasGlesComposition并且supportsFramebufferTarget或者virtual display)
- mDisplaySurface->advanceFrame(GL合成后调用)
- doComposeSurfaces
- doDisplayComposition(创建hwc_display_contents_1)
- hw->compositionComplete
- mDisplaySurface->compositionComplete(GL合成后调用,兼容老的实现)
- foreach mDisplays
- postFramebuffer
- hwc.commit
- foreach mDisplays
- hw->onSwapBuffersCompleted(hwc)
- mDisplaySurface->onFrameCommitted(HWC commit后调用)
- foreach mVisibleLayersSortedByZ
- layer->onLayerDisplayed(从HWC获取同步Fence)
- hwlayer->getAndResetReleaseFence
- mSurfaceFlingerConsumer->setReleaseFence
- layer->onLayerDisplayed(从HWC获取同步Fence)
- hw->onSwapBuffersCompleted(hwc)
- 合成后处理(postComposition)
- postComposition
- foreach mDrawingState.layersSortedByZ
- layer->onPostComposition(记录每帧图像的时间,用于dump)
- mSurfaceFlingerConsumer->getCurrentFence
- mFrameTracker.setFrameReadyFence
- hwc.getDisplayFence
- mFrameTracker.setActualPresentFence
- mFrameTracker.advanceFrame
- layer->onPostComposition(记录每帧图像的时间,用于dump)
- hwc.getDisplayFence
- mPrimaryDispSync.addPresentFence
- foreach mDrawingState.layersSortedByZ
本文详细介绍了Android系统中SurfaceFlinger如何处理硬件显示设备,包括虚拟显示设备的创建、VSync信号的处理、事务处理、失效更新及屏幕刷新等过程。SurfaceFlinger通过与HWComposer交互,管理屏幕合成,处理OpenGL和硬件Overlays的分工,确保显示的高效和准确。此外,还涉及了虚拟显示设备如Wi-FiDisplay(Miracast)的连接流程。
2769

被折叠的 条评论
为什么被折叠?



