「Android」SurfaceFlinger分析

「Android」SurfaceFlinger分析
本篇针对surfaceFlinger模块进⾏分析,⽬录如下:
1、SurfaceFlinger功能
  1.1、BufferQueue原理(native/libs/gui模块)
  1.2  layer显⽰内存分配(native/libs/ui模块)
  1.3、surfaceFlinger处理(native/.../surfaceFlinger模块)
2、⼯程代码解析:
  2.1、surfaceFlinger启动过程
  2.2、surfaceFlinger事务处理
3、总结(处理流程、交互模块)
***********************************************************×*********************************×*******
1、SurfaceFlinger功能:
surfaceflinger作⽤是接受多个来源的图形显⽰数据,将他们合成,然后发送到显⽰设备。
⽐如打开应⽤,常见的有三层显⽰,顶部的statusbar底部或者侧⾯的导航栏以及应⽤的界⾯,每个层是单独更新和渲染,这些界⾯都是有surfaceflinger合成⼀个刷新到硬件显⽰。
在显⽰过程中使⽤到了bufferqueue,surfaceflinger作为consumer⽅,⽐如windowmanager管理的surface作为⽣产⽅产⽣页⾯,交由surfaceflinger进⾏合成。
1.1、BufferQueue原理(和SF交互)
bufferqueue分为⽣产者和消费者
⽐如应⽤通过windowsmanager分配⼀个surface,需要分配(dequeueBuffer)显⽰空间在上⾯进⾏绘图,在图形绘制完成后需要推送(queueBuffer)到surfaceflinger进⾏合成显⽰。
surfaceflinger作为消费者,通过acquireBuffer()得到⼀个要合成的图形,在合成完毕后再releaseBuffer()将图形释放。
(1)在bufferQueuei所在⽬录下 ComposerService 为单例模式负责与surfaceflinger建⽴binder连接,在native/libs/gui库。
代码如下:
class ComposerService : public Singleton<ComposerService>
{
sp<ISurfaceComposer> mComposerService;
sp<IBinder::DeathRecipient> mDeathObserver;
Mutex mLock;
ComposerService();
void connectLocked();
void composerServiceDied();
friend class Singleton<ComposerService>;
public:
// Get a connection to the Composer Service.  This will block until
// a connection is established.即getComposerService
static sp<ISurfaceComposer> getComposerService();
};
(2)ComposerService 为单例模式负责与surfaceflinger建⽴binder连接;
(3)SurfaceComposerClient则在于surfaceflinger建⽴连接后(即getComposerService)建⽴与Client的连接,
  通过client调⽤createSurface,然后返回SurfaceControl;
(4)SurfaceControl负责这个显⽰层的控制。
sp<Surface> SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = new Surface(mGraphicBufferProducer, false);
}
return mSurfaceData;
罗口袜
}
通过SurfaceControl::getSurface(),得到的真正的显⽰层,这样之后可以通过Lock和unlock将surface空间分配绘图,再返回给surfaceflinger。1.2 layer显⽰内存分配
(1)surface创建后得到 mGraphicBufferProducer,new GraphicBuffer分配⼀个GraphicBuffer:
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {.....}
(2)在graphicbuffer.cpp中分配⼀个共享内存,在native/libs/ui模块:
GraphicBuffer::GraphicBuffer(...){...}
status_t GraphicBuffer::initWithSize(...){...}
(3)GraphicBufferAllocator::get() 使⽤gralloc进⾏内存分配,分配完成后,得到bufferIdx 将他发给client端也就是surface端
(4)返回虚拟地址给上层
1.3、surfaceFlinger处理
上⾯创建⼀个surface后,surfaceflinger对应的是⼀个layer,当上层layer调⽤刷新后,onFrameAvailable被调⽤,通知surfaceflinger有layer更新void BufferLayer::onFrameAvailable(const BufferItem& item) {
mFlinger->signalLayerUpdate();
}
无菌检测系统2、⼯程代码解析:
2.1、surfaceFlinger启动过程:
(代码取⾃其他博客提供下载的源码blog.csdn/ztguang/article/details/64905058,Android7.0以上)
1、surfaceFlinger代码仓位置:/frameworks/native/services/surfaceflingers
    surfaceFlinger启动进程的脚本是⽂件,内容如下:
1 service surfaceflinger /system/bin/surfaceflinger
2    class core
3    user system
4    group graphics drmrpc readproc
5    onrestart restart zygote
6    writepid /dev/stune/foreground/tasks
socket pdx/system/vr/display/client
stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager
stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync
stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
  注:在.bp脚本中会初始化该脚本,之后执⾏main_surfaceflinger.cpp⽂件(rc⽂件有3个socket,⽤于跨进程通信)
2、创建进程后执⾏main函数,main函数在frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp,main函数主要代码如下:
int main(int, char**) {
  //忽略了SIGPIPE信号,因为在SurfaceFlinger的Client-Server模型中,或者说IPC机制中,很可能会
触发SIGPIPE信号,⽽这个信号的默认动作是终⽌进程
  ////当客户端/服务端的socket关闭时,防⽌进程退出
signal(SIGPIPE, SIG_IGN);
// When SF is launched in its own process, limit the number of
// binder threads to 4.即SF进程开启后,线程池限制最⼤数量为4
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// start the thread pool即启动线程池
  //⼤多数程序都是需要IPC的,这⾥也需要,但是使⽤Binder机制是很繁琐的,所以Android为程序进程使⽤Binder机制封装了两个实现类:ProcessState、IPCThreadState   //其中ProcessState负责打开Binder驱动,进⾏mmap等准备⼯作;IPCThreadState负责具体线程跟Binder驱动进⾏命令交互。
sp<processstate> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger即实例化,以及设置进程优先级、事物处理策略
sp<surfaceflinger> flinger = new SurfaceFlinger();
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
set_sched_policy(0, SP_FOREGROUND);
#ifdef ENABLE_CPUSETS
// Put most SurfaceFlinger threads in the system-background cpuset
// Keeps us from unnecessarily using big cores
// Do this after the binder thread pool init
set_cpuset_policy(0, SP_SYSTEM);
#endif
// initialize before clients can connect即初始化
flinger->init();
// publish surface flinger即发布SF,注册到ServiceManager,sp是strongponiter强指针(sp对象的析构函数调⽤RefBase的decStrong来减少强弱引⽤指针计数)
sp<iservicemanager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// publish GpuService即注册GPUservice
sp<gpuservice> gpuservice = new GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice, false);
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO");
}
// run surface flinger in this thread即运⾏当前线程
flinger->run();
return0;
}
在执⾏main函数的时候,执⾏经过了以下过程:
(1)创建SurfaceFlinger对象,在其构造函数中,主要是⼀些成员变量的初始化⼯作。在SurfaceFlinger.cpp中的构造函数代码如下:SurfaceFlinger::SurfaceFlinger()
:  BnSurfaceComposer(),
mTransactionFlags(0),
mTransactionPending(false),
mAnimTransactionPending(false),
mLayersRemoved(false),
mRepaintEverything(0),
mRenderEngine(NULL),
mBootTime(systemTime()),
mBuiltinDisplays(),
mVisibleRegionsDirty(false),
mGeometryInvalid(false),
mAnimCompositionPending(false),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
mDebugDisableTransformHint(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
mForceFullDamage(false),
mPrimaryDispSync("PrimaryDispSync"),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mHasColorMatrix(false),
mHasPoweredOff(false),
mFrameBuckets(),
mTotalTime(0),
mLastSwapTime(0)
{......}
(2)因为这⾥的SurfaceFlinger对象是⼀个StrongPointer(强指针,见⽼罗博客blog.csdn/luoshengyang/article/details/6786239),所以⾸先会⾛到RefBase的onFirstRef⽅法。
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
查看surfaceFlinger.h,发现mEventQueue是MessqgeQueue创建的对象。所以初始化会创建消息队列需要的Handler、Looper。在相同⽬录下的MessageQueue.cpp⽂件中:
void MessageQueue::init(const sp<surfaceflinger>& flinger)
{
mFlinger = flinger;
mLooper = new Looper(true);
mHandler = new Handler(*this);
}
  此处MessageQueue不是常见的消息队列,在surfaceFlinger⽬录单独编写,mEventQueue更像是消息循环机制的管理者,其中包含了⼀个looper,⼀个handler。
  looper中的mMessageEnvelopes这个容器才是真正存储消息的地⽅:
/* MessageQueue.cpp */
void MessageQueue::waitMessage() {
int32_tret = mLooper->pollOnce(-1);
}
  handler也不是常见的那个handler,⽽是Messagequeue中⾃定义的⼀个事件处理器,是专门为surfaceflinger设计的,handler收到消息,进⼀步回调surfaceflinger中的onMessageReceived。
void MessageQueue::Handler::handleMessage(constMessage& message) {
switch(message.what) {
caseINVALIDATE:
mQueue.mFlinger->onMessageReceived(message.what);
}        }
(3)之后执⾏surfaceFlinger::init,⽅法主要实现的功能:
初始化EGL
创建HWComposer
初始化⾮虚拟显⽰屏
启动EventThreada线程
启动开机动画
在SurfaceFlinger.cpp中的代码如下:
void SurfaceFlinger::init() {
ALOGI(  "SurfaceFlinger's main thread ready to run. "
"Initializing graphics ");  //开始SF线程的准备⼯作,初始化graphics H/W
{ // Autolock scope
Mutex::Autolock _l(mStateLock);
// initialize EGL for the default display即初始化EGL,作为默认显⽰(EGL见blog.csdn/ieearth/article/details/71180457)
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
// start the EventThread开启事件线程
电厂巡检机器人sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc, *this);
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, true, "sf");捞泥
mSFEventThread = new EventThread(sfVsyncSrc, *this);
mEventQueue.setEventThread(mSFEventThread);
// set SFEventThread to SCHED_FIFO to minimize jitter
struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(mSFEventThread->getTid(), SCHED_FIFO, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO for SFEventThread");
}
// Get a RenderEngine for the given display / config (can't fail)
mRenderEngine = RenderEngine::create(mEGLDisplay,
HAL_PIXEL_FORMAT_RGBA_8888);
}
// Drop the state lock while we initialize the hardware composer. We drop
// the lock because on creation, it will call back into SurfaceFlinger to
/
/ initialize the primary display.即初始化硬件composer对象,和显⽰设备交互,硬件显⽰设备
mHwc = new HWComposer(this);
mHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
小型地源热泵Mutex::Autolock _l(mStateLock);
// retrieve the EGL context that was selected/created即检索创建的EGL上下⽂
mEGLContext = mRenderEngine->getEGLContext();
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
// make the GLContext current so that we can create textures when creating
// Layers (which may happens before we render something)即显⽰设备
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);//创建EventControl
// initialize our drawing state
mDrawingState = mCurrentState;
// set initial conditions (e.g. unblank default device)即初始化显⽰装备
initializeDisplays();
防误闭锁mRenderEngine->primeCache();
// start boot animation即启动开机动画
startBootAnim();
ALOGV("Done initializing");
}
(4)Android系统中有⼀个ServiceManager,专门⽤来管理所有的服务,⽽SurfaceFlinger不是由ServiceManager启动的,因此需要向ServiceManager注册SurfaceFlinger,同时还注册了GpuService。(在main函数⾥⾯注册)
(5)执⾏SF的run⽅法,SurfaceFlinger::run,进⼊消息循环,SurfaceFlinger启动成功,开始⼯作。代码如下:
void SurfaceFlinger::run() {
do {
waitForEvent();
} while (true);
}
(分析参考博客blog.csdn/u012439416/article/details/79733178)
waitForEvent⽅法如下:
mEventQueue.waitMessage();
MessageQueue的waitMessage⽅法也是⼀个do – while循环,⾥⾯逻辑如下:

本文发布于:2024-09-23 08:23:00,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/3/329502.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:启动   进程   分配
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议