Android 源码分析 - 显示 - 数据流

本文详细介绍了Android系统中SurfaceFlinger如何处理硬件显示设备,包括虚拟显示设备的创建、VSync信号的处理、事务处理、失效更新及屏幕刷新等过程。SurfaceFlinger通过与HWComposer交互,管理屏幕合成,处理OpenGL和硬件Overlays的分工,确保显示的高效和准确。此外,还涉及了虚拟显示设备如Wi-FiDisplay(Miracast)的连接流程。
部署运行你感兴趣的模型镜像

硬件显示设备

        在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
  1. eglGetDisplay
  2. eglInitialize
  3. new HWComposer
  4. RenderEngine::create
  • 初始化内建显示设备
  1. for i = 0 ~ NUM_BUILTIN_DISPLAY_TYPES
    1. new BufferQueue
    2. new FramebufferSurface
    3. new DisplayDevice
    4. mDisplays.add
  • 初始化辅助线程,消息队列
  1. new DispSyncSource
  2. new EventThread
  3. new DispSyncSource
  4. new EventThread
  5. mEventQueue.setEventThread
  6. new EventControlThread
  • 其他
  1. initializeDisplays
    1. postMessageAsync(MessageScreenInitialized)
  2. startBootAnim

VSync信号

  • HWComposer收到VSync回调(HWComposer::vsync)
  1. HWComposer::vsync
    1. mEventHandler.onVSyncReceived(EventHandler接口,由SurfaceFlinger实现)
  • SurfaceFlinger处理VSync回调(SurfaceFlinger::onVSyncReceived)
  1. SurfaceFlinger::onVSyncReceived
    1. if (type == 0 && mPrimaryHWVsyncEnabled)(type实际是Display id,只处理主屏幕的vsync)
      1. needsHwVsync = mPrimaryDispSync.addResyncSample(送到DispSync)
    2. if (needsHwVsync)
      1. enableHardwareVsync
    3. else
      1. disableHardwareVsync
  • DispSync计算VSync统计变量(DispSync::addResyncSample)

DispSync需要同步硬件Vsync,通过beginResync、addResyncSample、endResync做一次重新同步。addResyncSample需要多次调用知道返回false表示同步完成。

  1. DispSync::addResyncSample
    1. 添加当前Vsync时间戳到循环数组,只记录最近若干采样
    2. updateModelLocked
    3. 计算周期(mPeriod)和偏移(mPhase),偏移相对于时间0开始的周期信号
    4. mThread->updateModel(更新到内部线程DispSyncThread)
  • DispSyncThread产生软件VSync信号(DispSyncThread::threadLoop)

DispSyncThread为多个客户端(Listener)产生不同偏移(相对于硬件Vsync)的周期信号。

  1. DispSyncThread::threadLoop
    1. computeNextEventTimeLocked
      1. foreach mEventListeners(计算每个Listener的下一个信号时间)
        1. computeListenerNextEventTimeLocked
          1. 下一个时间0开始的周期信号加上硬件偏移和客户端指定偏移
        2. 取最小值
    2. mCond.waitRelative(等待到下一个信号时间)
    3. gatherCallbackInvocationsLocked(收集到期的信号回调)
    4. fireCallbackInvocations(调用回调,DispSync::Callback接口,由DispSyncSource实现)
  • DispSyncSource将软件VSync发送给注册的回调(DispSyncSource::onDispSyncEvent)

DispSyncSource纯粹是为了接口转换,可能是兼容的原因。

  1. DispSyncSource::onDispSyncEvent
    1. callback->onVSyncEvent(VSyncSource::Callback接口,由EventThread实现)
  • EventThread记录VSync信号,转换为内部事件
  1. EventThread::onVSyncEvent
    1. mVSyncEvent[0].vsync.count++(DisplayEventReceiver::Event类型)
    2. mCondition.broadcast(唤醒内部线程
  • EventThread内部线程将软件VSync发送给注册客户端(EventThread::threadLoop)
  1. EventThread::threadLoop
    1. waitForEvent(等待事件,并返回感兴趣的连接EventThread::Connection)
      1. foreach mVSyncEvent(数组只有第一个可能会有Vsync事件)
        1. if (event.header.timestamp)
      2. foreach mDisplayEventConnections(所有连接)
        1. 根据connection->count(0,接收一次,变为-1,>0,如果整除,接收)
    2. foreach signalConnections
      1. conn->postEvent(event)
        1. DisplayEventReceiver::sendEvents
          1. BitTube::sendObjects(通过BitTube管道发送事件)
  • MessageQueue接收事件(MessageQueue::cb_eventReceiver)

MessageQueue在内部线程(Looper)注册BitTube句柄,当句柄上有数据时,调用注册的回调cb_eventReceiver。

  1. MessageQueue::cb_eventReceiver
    1. queue->eventReceiver
      1. while (DisplayEventReceiver::getEvents)(从BitTube管道读取事件)
        1. if (buffer[i].header.type == DISPLAY_EVENT_VSYNC)
          1. #if INVALIDATE_ON_VSYNC
            1. mHandler->dispatchInvalidate();
              1. mQueue.mLooper->sendMessage(发送消息)
          2. #else
            1. mHandler->dispatchRefresh();
              1. mQueue.mLooper->sendMessage(发送消息)
          3. #endif
  • MessageQueue处理消息(MessageQueue::Handler::handleMessage)
  1. MessageQueue::Handler::handleMessage
    1. mQueue.mFlinger->onMessageReceived(SurfaceFlinger处理消息,详见下文)

增加虚拟屏幕

  • 应用层调用方式(TODO:示例源代码)
  1. new SurfaceComposerClient(创建到SurfaceFlinger的客户端连接)
  2. createDisplay(创建虚拟屏幕)
    1. Composer::getInstance().createDisplay
      1. ComposerService::getComposerService()->createDisplay
  3. openGlobalTransaction(打开一个事务)
    1. Composer::openGlobalTransaction
  4. setDisplaySurface(设置虚拟屏幕表面Surface)
    1. Composer::getInstance().setDisplaySurface
  5. setDisplayLayerStack(设备虚拟屏幕图层镜像)
    1. Composer::getInstance().setDisplayLayerStack
  6. setDisplayProjection(设备虚拟屏幕投影区域)
    1. Composer::getInstance().setDisplayProjection
  7. closeGlobalTransaction(提交事务)
    1. Composer::closeGlobalTransaction
      1. Composer::getInstance().closeGlobalTransactionImpl
        1. sm->setTransactionState
  • SurfaceFlinger创建虚拟屏幕(SurfaceFlinger::createDisplay)
  1. SurfaceFlinger::createDisplay
    1. new DisplayToken(Binder对象,用来自动释放)
    2. DisplayDeviceState(DisplayDevice::DISPLAY_VIRTUAL)
    3. mCurrentState.displays.add(添加到读取状态,后面与事务一起处理)
  • SurfaceFlinger处理客户端事务(SurfaceFlinger::setTransactionState)
  1. SurfaceFlinger::setTransactionState
    1. foreach displays(外部更新状态)
      1. setDisplayStateLocked
        1. mCurrentState.displays.indexOfKey(查找内部数组对应屏幕)
        2. if (what & DisplayState::eSurfaceChanged)(屏幕表面变化)
          1. flags |= eDisplayTransactionNeeded
        3. if (what & DisplayState::eLayerStackChanged)(图层栈变化)
          1. flags |= eDisplayTransactionNeeded
    2. if (transactionFlags)
      1. setTransactionFlags
        1. signalTransaction
          1. mEventQueue.invalidate(排队Invalidate消息)
  • SurfaceFlinger处理增加虚拟屏幕事务(SurfaceFlinger:: handleMessageTransaction)

Invalidate消息处理,包含事务处理(handleMessageTransaction,详见“事务处理”),这里列举增加虚拟屏幕相关的部分。

  1. SurfaceFlinger::handleMessageTransaction
    1. handleTransactionLocked
      1. if (transactionFlags & eDisplayTransactionNeeded)
        1. 比较mCurrentState和mDrawingState,对增加的屏幕
          1. if (DisplayDeviceState::isVirtualDisplay)
            1. allocateHwcDisplayId(申请硬件虚拟屏幕ID,可能失败)
            2. new BufferQueue(GLES合成的表面)
            3. new VirtualDisplaySurface
          2. new DisplayDevice

连接WifiDisplay

  • DisplayManager启动连接Wifi设备(connectWifiDisplay)
  1. DisplayManagerGlobal.connectWifiDisplay()
    1. mDm.connectWifiDisplay()【DisplayManagerService】
      1. mWifiDisplayAdapter.requestConnectLocked()
        1. mDisplayController.requestConnect()
          1. connect()
            1. updateConnection()
  • WifiDisplayController更新连接状态(updateConnection)
  1. 关闭老的设备连接【略过】
  2. new WifiP2pConfig()
  3. new WpsInfo()
  4. createWifiDisplay()
  5. advertiseDisplay()【清空老的记录】
  6. mWifiP2pManager.connect()【Wifi P2P连接】
  7. 等待WIFI_P2P_CONNECTION_CHANGED_ACTION
  • WifiDisplayController处理P2p连接变化广播(mWifiP2pReceiver)
  1. mWifiP2pReceiver.onReceive()
    1. handleConnectionChanged()
      1. mWifiP2pManager.requestGroupInfo()【等待回调】
  2. GroupInfoListener.onGroupInfoAvailable()【requestGroupInfo回调】
    1. updateConnection()【根据当前状态,应该到第6步】
      1. mWifiP2pManager.setMiracastMode()
      2. RemoteDisplay.listen()【侦听远端设备RTSP连接】
  • RemoteDisplay启动侦听
  1. RemoteDisplay.listen()
    1. new RemoteDisplay()
    2. display.startListening
      1. nativeListen()【JNI】
        1. IServiceManager->getService()【IMediaPlayerService,"media.player"】
        2. new NativeRemoteDisplayClient【IRemoteDisplayClient】
        3. IMediaPlayerService->listenForRemoteDisplay()【返回IRemoteDisplay】
        4. new NativeRemoteDisplay()【包装IRemoteDisplay】
  • RemoteDisplay收到连接
  1. NativeRemoteDisplayClient::onDisplayConnected(IGraphicBufferProducer)
    1. android_view_Surface_createFromIGraphicBufferProducer()
      1. new Surface()【提供数据方】
    2. RemoteDisplay.notifyDisplayConnected()【从JNI回调】
    3. mHandler.post(mListener.onDisplayConnected())【Handler线程调用回调】
  • WifiDisplayController处理成功消息
  1. RemoteDisplay.Listener.onDisplayConnected()
    1. mListener.onDisplaySessionInfo()【WifiDisplayAdapter】
      1. mWifiDisplayListener.onDisplaySessionInfo()
    2. createWifiDisplay()
    3. advertiseDisplay()
      1. mHandler.post()【Handler线程post onDisplayConnected】
  • WifiDisplayAdapter处理成功消息
  1. mListener.onDisplayConnected()
    1. mWifiDisplayListener.onDisplayConnected()
      1. addDisplayDeviceLocked()
        1. new WifiDisplayDevice()
        2. sendDisplayDeviceEventLocked()
          1. mHandler.post()【mListener.onDisplayDeviceEvent(),通知到DisplayManagerService】
      2. scheduleStatusChangedBroadcastLocked()【异步发送广播DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED】
      3. scheduleUpdateNotificationLocked()【异步更新通知栏UI】
  • DisplayManagerService处理成功消息
  1. DisplayAdapterListener.onDisplayDeviceEvent()
    1. DisplayManagerService.handleDisplayDeviceAdded()
      1. handleDisplayDeviceAddedLocked()
        1. mDisplayDevices.add()
        2. addLogicalDisplayLocked()
          1. new LogicalDisplay()
          2. mLogicalDisplays.put()
          3. sendDisplayEventLocked()【异步回调IDisplayManagerCallback.notifyDisplayEventAsync(),DisplayManagerGlobal.EVENT_DISPLAY_ADDED】
        3. updateDisplayBlankingLocked()【与PowerManager屏幕状态一致】
        4. scheduleTraversalLocked()【异步请求mWindowManagerFuncs.requestTraversal()】
  • DisplayManagerService处理更新事务
  1. performTraversalInTransactionFromWindowManager()
    1. performTraversalInTransactionLocked()
      1. handleDisplayDeviceAddedLocked()
      2. foreach device : mDisplayDevices
        1. configureDisplayInTransactionLocked()
          1. findLogicalDisplayForDeviceLocked()
          2. display.configureDisplayInTransactionLocked()
            1. device.setLayerStackInTransactionLocked()
            2. device.setProjectionInTransactionLocked()
        2. device.performTraversalInTransactionLocked()
          1. setSurfaceInTransactionLocked()【WifiDisplayDevice】

消息处理

        SurfaceFlinger在onMessageReceived中处理消息,调用线程是MessageQueue线程。

        在处理TRANSACTION消息时,需要做事务处理。

        在处理INVALIDATE消息时,先做事务处理,然后更新失效区域,最后在MessageQueue中安排一个REFRESH消息。

        在处理REFRESH消息时,做屏幕刷新。

事务处理(Transaction)

  • SurfaceFlinger在handleMessageTransaction中处理事务
  1. handleMessageTransaction
    1. handleTransaction(transactionFlags)
      1. handleTransactionLocked(具体的事务处理)
      2. invalidateHwcGeometry()
        1. mHwWorkListDirty = true
  • 具体的事务处理过程
  1. handleTransactionLocked
    1. if (transactionFlags & eTraversalNeeded)(这里只处理layer内部的事务)
    2. if (transactionFlags & eDisplayTransactionNeeded)(处理设备插拔事务)
    3. if (transactionFlags & eTraversalNeeded| eDisplayTransactionNeeded)(更新layer到Display的角度转换)
    4. if (mLayersRemoved)(处理layer删除)
    5. commitTransaction(提交事务完成)
  • layer内部事务处理过程
  1. foreach mCurrentState.layersSortedByZ
    1. if (!layer->getTransactionFlags) continue(该layer没有事务)
    2. layer->doTransaction(返回变化的状态,记录可见区域变化)
  • 设备插拔事务处理过程
  1. foreach mDrawingState.displays
    1. 如果mCurrentState.displays没有对应的(删除)
      1. DisplayDevice::disconnect(hwc)
      2. mEventThread->onHotplugReceived
    2. 如果有对应的(保留)
      1. Surface变化
        1. 删除(稍后会添加),continue
      2. DisplayDevice::setLayerStack(layerStack变化)
      3. DisplayDevice::setProjection(orientation、viewport、frame变化)
  2. foreach mCurrentState.displays
    1. 如果mDrawingState.displays没有对应的(增加)
      1. if (DisplayDeviceState::isVirtualDisplay)
        1. allocateHwcDisplayId
        2. new BufferQueue(new GraphicBufferAlloc())
        3. new VirtualDisplaySurface
      2. else
        1. allocateHwcDisplayId
        2. new FramebufferSurface
      3. new DisplayDevice
      4. mEventThread->onHotplugReceived
  • 更新layer到Display的角度转换
  1. foreach mCurrentState.layersSortedByZ
    1. 如果layerStack变化(因为先根据layerStack排序,可以减少查找次数)
      1. 查找对应的Display,没有一一对应关系,使用默认Display
    2. layer->updateTransformHint(disp)
  • 处理layer删除
  1. foreach mDrawingState.layersSortedByZ
    1. 如果mCurrentState.layersSortedByZ没有对应的(删除)
      1. invalidateLayerStack
  • 提交事务完成
  1. foreach mLayersPendingRemoval
    1. layer->onRemoved
  2. mDrawingState = mCurrentState

失效更新(Invalidate)

  • SurfaceFlinger在handleMessageInvalidate中处理失效更新
  1. handleMessageInvalidate
    1. handlePageFlip
      1. foreach layers
        1. layer->latchBuffer(锁住当前缓存,返回失效区域,还返回是否需要重新计算可见区域)
        2. layer->getDrawingState
        3. invalidateLayerStack(更新显示设备的失效区域)
      2. mVisibleRegionsDirty|= visibleRegions(可见区域失效)
  • layer锁住当前缓存
  1. Layer::latchBuffer
    1. SurfaceFlingerConsumer::updateTexImage
    2. 如果上面返回BufferQueue::PRESENT_LATER
      1. SurfaceFlinger::signalLayerUpdate(再次安排更新任务)
      2. 返回空区域
    3. if (--mQueuedFrames)(多个排队缓存)
      1. SurfaceFlinger::signalLayerUpdate(再次安排更新任务)
    4. SurfaceFlingerConsumer::getCurrentBuffer
    5. 如果crop、transform、scalingMode,bufWidth、bufHeight、Opacity变化了
      1. recomputeVisibleRegions = true(需要重新计算可见区域)
    6. s.active.w、s.active.h、s.transform计算出outDirtyRegion(这里只是简单使用整个区域)
  • 更新显示设备的失效区域
  1. invalidateLayerStack
    1. 根据layerStack查找mDisplays
    2. hw->dirtyRegion.orSelf(dirty)

屏幕刷新(Refresh)

  • SurfaceFlinger在handleMessageRefresh中处理屏幕刷新
  1. handleMessageRefresh
    1. preComposition(预处理)
    2. rebuildLayerStacks(重构Layer栈)
    3. setUpHWComposer(构建硬件合成工作序列)
    4. doDebugFlashRegions
    5. doComposition(合成layers)
    6. postComposition(合成后处理)
  • 预处理(preComposition)
  1. preComposition
    1. foreach mDrawingState.layersSortedByZ
      1. if (layer->onPreComposition)(如果有等待的缓存,返回true)
        1. needExtraInvalidate = true
    2. if (needExtraInvalidate)
      1. signalLayerUpdate(排队新的更新消息)
  • 重构Layer栈(rebuildLayerStacks)
  1. rebuildLayerStacks(mVisibleRegionsDirty为真时有用)
    1. invalidateHwcGeometry(设置几何拓扑失效标志)
    2. foreach mDisplays
      1. computeVisibleRegions(计算各个layer的失效区域,透明区域等等)
  • 构建硬件合成工作序列(setUpHWComposer)
  1. setUpHWComposer
    1. foreach mDisplays
      1. hw->beginFrame
        1. mDisplaySurface->beginFrame(HWC prepare前调用)
    2. if (mHwWorkListDirty)(几何拓扑失效,在事务处理时或者可见区域变化时设置)
      1. foreach mDisplays
        1. hwc.createWorkList(创建hwc_display_contents_1)
    3. foreach mDisplays
      1. foreach mVisibleLayersSortedByZ
        1. layer->setPerFrameData(传递图像缓存到HWC图层)
          1. hwcLayer.setBuffer
    4. hwc.prepare
    5. foreach mDisplays
      1. hw->prepareFrame
        1. mDisplaySurface->prepareFrame(HWC prepare后调用)
  • 合成layers(doComposition)
  1. doComposition
    1. foreach mDisplays
      1. doDisplayComposition(创建hwc_display_contents_1)
        1. doComposeSurfaces
          1. getRenderEngine
          2. if (hasGlesComposition)
            1. hw->makeCurrent
            2. if (hasHwcComposition)
              1. engine.clearWithColor
            3. else
              1. drawWormhole
                1. engine.fillRegionWithColor
          3. if (cur != end)(使用HWC)
            1. foreach mVisibleLayersSortedByZ
              1. switch (cur->getCompositionType())
                1. case HWC_OVERLAY
                  1. layer->clearWithOpenGL
                2. case HWC_FRAMEBUFFER
                  1. layer->draw
              2. layer->setAcquireFence(传递同步Fence到HWC)
                1. mSurfaceFlingerConsumer->getCurrentFence
                2. hwlayer.setAcquireFenceFd
          4. else(没有使用HWC)
            1. foreach mVisibleLayersSortedByZ
              1. layer->draw
        2. hw->swapBuffers
          1. eglSwapBuffers(如果没有HWC,或者hasGlesComposition并且supportsFramebufferTarget或者virtual display)
          2. mDisplaySurface->advanceFrame(GL合成后调用)
    2. hw->compositionComplete
      1. mDisplaySurface->compositionComplete(GL合成后调用,兼容老的实现)
  2. postFramebuffer
    1. hwc.commit
    2. foreach mDisplays
      1. hw->onSwapBuffersCompleted(hwc)
        1. mDisplaySurface->onFrameCommitted(HWC commit后调用)
      2. foreach mVisibleLayersSortedByZ
        1. layer->onLayerDisplayed(从HWC获取同步Fence)
          1. hwlayer->getAndResetReleaseFence
          2. mSurfaceFlingerConsumer->setReleaseFence
  • 合成后处理(postComposition)
  1. postComposition
    1. foreach mDrawingState.layersSortedByZ
      1. layer->onPostComposition(记录每帧图像的时间,用于dump)
        1. mSurfaceFlingerConsumer->getCurrentFence
        2. mFrameTracker.setFrameReadyFence
        3. hwc.getDisplayFence
        4. mFrameTracker.setActualPresentFence
        5. mFrameTracker.advanceFrame
    2. hwc.getDisplayFence
      1. mPrimaryDispSync.addPresentFence

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting Horse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值