Android SurfaceFlinger中的工作线程:threadLoop()

本文深入探讨SurfaceFlinger线程循环的工作原理,从处理显示设备状态变化到页面翻转阶段,详细解析各个关键步骤如何确保实时更新和高效渲染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SurfaceFlinger继承了Thread类,自然也继承了Thread类的threadLoop方法,SurfaceFlinger工作线程的主代码都在threadLoop()方法中。工作线程启动后,基类Thread会循环地调用threadLoop方法,SurfaceFlinger的threadLoop()主要是要完成系统中各个Layer(Surface)进行混合(compose),然后不停地把一帧帧混合好的图像数据传送到显示设备中。

 

threadLoop的流程

                 图一   threadLoop流程

1. handleConsoleEvents

handleConsoleEvent目前没有深入了解,貌似只是处理显示设备进入休眠状态或者从休眠中唤醒时,改变SufaceFlinger的状态,然后threadLoop的后续流程会根据相应的状态来决定是否继续给显示设备传送显示数据。

2. handleTransaction

因为Layer的混合是在线程中进行的,而混合的过程中,应用程序或者系统可能会改变Layer的状态,例如屏幕旋转、增加或删除Layer、某个Layer可见或不可见,为了使这些变动不会破坏当前正在进行的混合动作,SurfaceFlinger维护着两个Layer列表:

  • mCurrentState.layersSortedByZ   ---- 当前系统最新的Layer列表
  • mDrawingState.layersSortedByZ  ---- 本次混合操作使用的Layer列表

handleTransaction就是根据Layer列表的这些状态的变化,计算是否有可见区域内需要更新,并设置状态变量mVisibleRegionsDirty,然后把mCurrentState赋值给mDrawingState,最后释放已经被丢弃(ditch)的Layer

  • 上一次混合过程中,可能应用程序释放了一个Layer,可是mDrawingState正在使用,不能马上销毁,所以要等到本次混合前才能做出销毁的动作。

  • 如果Layer的大小有变化并且可见,Layer的handleTransaction将会重新分配缓冲区,并且冻结SurfaceFlinger后续的混合操作,也就是屏幕的内容本次将不会刷新,直到下一个循环的handlePageFlip阶段才解除冻结。

3. handlePageFlip

该阶段会遍历各个Layer,在每个Layer中,取得并锁住该Layer的frontBuffer,然后利用frontBuffer中的图像数据生成该Layer的2D贴图(Texture),并且计算更新区域,为后续的混合操作做准备。

                                图二   handlePageFlip处理流程

Layer的lockPageFlip()首先通过SharedBufferServer类的成员变量lcblk,调用retireAndLock取得该Layer当前可用的frontBuffer,然后通过reloadTexture方法生成openGL ES的纹理贴图,最后通过unlockPageFlip完成更新区域的Layer坐标到屏幕坐标的变换。

handleRepaint

 handleRepaint真正实现Layer混合的阶段,下图是handleRepaint的处理流程:

                                                     图三  handleRepaint 的处理流程

 

handleRepaint首先重置了openGL的观察矩阵,然后遍历mDrawingState.layersSortedByZ 中的Layer列表,调用每个Layer的onDraw方法,在onDraw方法中,会调用drawWithOpenGL()方法,将在handlePageFlip阶段生成的贴图混合到OpenGL的主表面,最后handleRepaint把需要刷新的区域清除。

unlockClients

unlockClients只是遍历各个Layer并调用各个Layer的finishPageFlip方法。finishPageFlip会进一步调用SharedBufferServer的unlock()方法:(关于SharedBufferSever,请参考本人以下博文的SharedClient 和 SharedBufferStack一节)

[c-sharp] view plain copy
  1. void Layer::finishPageFlip()  
  2. {  
  3.     status_t err = lcblk->unlock( mFrontBufferIndex );  
  4.     LOGE_IF(err!=NO_ERROR,   
  5.             "layer %p, buffer=%d wasn't locked!",  
  6.             this, mFrontBufferIndex);  
  7. }  

 lcblk->unlock( mFrontBufferIndex )会把Layer的frontBuffer解除锁定。

postFramebuffer

 进入postFramebuffer阶段,OpenGL主表面已经准备好了混合完成的图像数据,postFramebuffer只是简单地调用hw.flip(),hw.flip()进一步调用了eglSwapBuffers完成主表面的切换,这样屏幕上的图像就会更新为新的数据。


08-19 15:05:43.362 2758 7213 D Battery : ThermalStatusListener: status = 3, temp = 34.4, heatInfo 08-19 15:05:43.369 1746 2211 D JobSchedulerServiceExtImpl: updateOsenseRestrictMode for 1 false false 08-19 15:05:43.399 11045 11045 F DEBUG : Process name is com.oplus.camera, uid is 10178, not key_process 08-19 15:05:43.400 11045 11045 F DEBUG : keyProcess: 0 08-19 15:05:43.400 11045 11045 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 08-19 15:05:43.400 11045 11045 F DEBUG : Build fingerprint: 'realme/RMX5111IN/RE6444L1:15/AP3A.240617.008/V.R4T2.39c8226-1a7c5d5-1ab41d2:user/release-keys' 08-19 15:05:43.400 11045 11045 F DEBUG : Revision: '0' 08-19 15:05:43.400 11045 11045 F DEBUG : ABI: 'arm64' 08-19 15:05:43.400 11045 11045 F DEBUG : Timestamp: 2025-08-19 15:05:43.019404185+0800 08-19 15:05:43.400 11045 11045 F DEBUG : Process uptime: 11s 08-19 15:05:43.400 11045 11045 F DEBUG : Cmdline: com.oplus.camera 08-19 15:05:43.400 11045 11045 F DEBUG : pid: 10408, tid: 10659, name: HwBinder:10408_ >>> com.oplus.camera <<< 08-19 15:05:43.400 11045 11045 F DEBUG : uid: 10178 08-19 15:05:43.400 11045 11045 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) 08-19 15:05:43.400 11045 11045 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000100008047 08-19 15:05:43.400 11045 11045 F DEBUG : x0 0000000000000001 x1 0000007b592f31e8 x2 0000000000000000 x3 0000000000000003 08-19 15:05:43.400 11045 11045 F DEBUG : x4 0000000000000072 x5 0000007b592f1502 x6 0000000000000031 x7 7f7f7f7f7f7f7f7f 08-19 15:05:43.400 11045 11045 F DEBUG : x8 0000007ba4bd7ba3 x9 0000000000000022 x10 000000000000006c x11 fffffffffffffffd 08-19 15:05:43.400 11045 11045 F DEBUG : x12 0000007b592f1930 x13 0000000000000062 x14 0000007b592f2cc8 x15 00000000ffffffa5 08-19 15:05:43.400 11045 11045 F DEBUG : x16 0000000000000001 x17 0000007da0769210 x18 0000007b4f668000 x19 0000007b592f40f0 08-19 15:05:43.400 11045 11045 F DEBUG : x20 00000000ffffffff x21 0000007ba4bf54b8 x22 0000007bbe3f60b0 x23 0000007b592f4a80 08-19 15:05:43.400 11045 11045 F DEBUG : x24 0000007ba503e8a8 x25 0000007b592f4a80 x26 0000007b592f42f0 x27 0000007b592f31d0 08-19 15:05:43.400 11045 11045 F DEBUG : x28 0000000100008047 x29 0000007b592f4090 08-19 15:05:43.400 11045 11045 F DEBUG : lr 0000007ba4c35454 sp 0000007b592f3100 pc 0000007ba4c35478 pst 0000000060001000 08-19 15:05:43.400 11045 11045 F DEBUG : 12 total frames 08-19 15:05:43.400 11045 11045 F DEBUG : backtrace: 08-19 15:05:43.400 11045 11045 F DEBUG : #00 pc 0000000000114478 /odm/lib64/libAlgoProcess.so (android::ISPDeviceCallback::processResult(vendor::mediatek::hardware::camera::isphal::V1_0::ISPResult const&)+392) (BuildId: b4b245ecd6bb8392bdbc139b15a30bd6) 08-19 15:05:43.400 11045 11045 F DEBUG : #01 pc 0000000000116488 /odm/lib64/libAlgoProcess.so (android::ISPDeviceCallbackWrapper::processResult(vendor::mediatek::hardware::camera::isphal::V1_0::ISPResult const&)+56) (BuildId: b4b245ecd6bb8392bdbc139b15a30bd6) 08-19 15:05:43.400 11045 11045 F DEBUG : #02 pc 0000000000016b68 /odm/lib64/vendor.mediatek.hardware.camera.isphal@1.0.so (vendor::mediatek::hardware::camera::isphal::V1_0::BnHwCallback::_hidl_processResult(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+184) (BuildId: 144461df563eeca43a2519742780e5f4) 08-19 15:05:43.400 11045 11045 F DEBUG : #03 pc 0000000000016f20 /odm/lib64/vendor.mediatek.hardware.camera.isphal@1.0.so (vendor::mediatek::hardware::camera::isphal::V1_0::BnHwCallback::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+240) (BuildId: 144461df563eeca43a2519742780e5f4) 08-19 15:05:43.400 11045 11045 F DEBUG : #04 pc 0000000000083750 /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+156) (BuildId: 0b7c7ec657276a97287f4882b617fa4a) 08-19 15:05:43.400 11045 11045 F DEBUG : #05 pc 000000000008870c /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::IPCThreadState::executeCommand(int)+2784) (BuildId: 0b7c7ec657276a97287f4882b617fa4a) 08-19 15:05:43.400 11045 11045 F DEBUG : #06 pc 0000000000087acc /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::IPCThreadState::getAndExecuteCommand()+224) (BuildId: 0b7c7ec657276a97287f4882b617fa4a) 08-19 15:05:43.400 11045 11045 F DEBUG : #07 pc 0000000000088c98 /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::IPCThreadState::joinThreadPool(bool)+172) (BuildId: 0b7c7ec657276a97287f4882b617fa4a) 08-19 15:05:43.400 11045 11045 F DEBUG : #08 pc 0000000000094220 /apex/com.android.vndk.v33/lib64/libhidlbase.so (android::hardware::PoolThread::threadLoop()+24) (BuildId: 0b7c7ec657276a97287f4882b617fa4a) 08-19 15:05:43.400 11045 11045 F DEBUG : #09 pc 0000000000012f18 /apex/com.android.vndk.v33/lib64/libutils.so (android::Thread::_threadLoop(void*)+416) (BuildId: c200e9a85d2415f28f0687a94e6b8643) 08-19 15:05:43.400 11045 11045 F DEBUG : #10 pc 00000000000a67a4 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+196) (BuildId: b963824e1119e1e9ec07440f1ee81f14) 08-19 15:05:43.400 11045 11045 F DEBUG : #11 pc 0000000000097b20 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: b963824e1119e1e9ec07440f1ee81f14) 08-19 15:05:43.410 855 936 I OriginChannel: pwm_rgb: lux:156, time_delta:0.000000, pwm_turbo:100, bri:0, r:1982, g:4959, b:4185, c:2664, elgo:11213, end:2, ts-5476376605716643840 08-19 15:05:43.411 1000 3384 D SurfaceFlinger: captureDisplay from pid 1000 uid -1 display 4627039422300187648 08-19 15:05:43.411 1746 1897 D Arc[OplusBrightnessPhoneStateManager]: LuxEvent{event:MAIN_LUX lux:66.0} -> LuxEvent{event:MAIN_LUX lux:66.0} 08-19 15:05:43.421 1746 2091 V InputReader: notifyMotion - id=daf0cb0 eventTime=3312688838000, deviceId=2, source=TOUCHSCREEN, displayId=0, policyFlags=0x0,
最新发布
08-21
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值