07.显示系统:第005课_Vsync机制:第005节_surfaceflinger对vsync的处理

上小节我们讲解了surface使用vsync的过程,并且分析了他的代码,我们下载来回顾一下:
假设我们的应用程序更新了一个界面,他会提交一个buffer给surfaceflinger,surfaceflinger发送一个Vsync请求给EventThread,EventThread又会把这个请求转发给DispSyncThread,DispSyncThread就会等待一个Vsync信号,当软件或者硬件的Vsync信号产生之后,他会唤醒DispSyncThread,DispSyncThread再去唤醒EventThread,然后EventThread给surfaceflinger发出一个Vsync信号,唤醒surfaceflinger。

EventThread是如何唤醒surfaceflinger的呢?实质是EventThread给surfaceflinger发送一个消息,surfaceflinger接收到这个消息之后,就会执行:

void SurfaceFlinger::onMessageReceived(int32_t what) {
	case MessageQueue::INVALIDATE: {
			bool refreshNeeded = handleMessageTransaction();
            refreshNeeded |= handleMessageInvalidate();
            signalRefresh();

进行处理,其发送的这个消息为MessageQueue::INVALIDATE类型。该小节我们就对

bool refreshNeeded = handleMessageTransaction();
	refreshNeeded |= handleMessageInvalidate();
	signalRefresh();

三个函数进行讲解。

前面提到,当应用程序提交数据给surfaceflinger,但是除了这种情况之外,他还要处理那些情况呢?如图:
在这里插入图片描述

一个android设备,其可能接有多个显示器(Dispaly),这些显示器有可能断开,也有可能接上。android设备也有多个APP,每个APP可能有多个surface,每个surface对应一个layer。这些layer会有内容更新,或者新的layer加入,老的layer移除,以及layer的属性变化(如:大小等等)与界面形状的改变。显然surfaceflinger对以上方式都能进行处理。

在讲解代码之前,我们先引入两个结构体,

结构体分析

在这里插入图片描述
打开surfaceflinger.h:

struct State {
        LayerVector layersSortedByZ;
        DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
    };
    /*定义了两个成员*/
    State mDrawingState;//正在使用或者上次使用的状态
    State mCurrentState;//当前或者被修改的状态

struct State 存在成员displays,State mDrawingState与State mCurrentState一做比较我们就知道displays是否发生了add或者remove。

打开layer.h

struct State {
        Geometry active;
        Geometry requested;
        uint32_t z;
        uint32_t layerStack;
#ifdef USE_HWC2
        float alpha;
#else
        uint8_t alpha;
#endif
        uint8_t flags;
        uint8_t mask;
        uint8_t reserved[2];
        int32_t sequence; // changes when visible regions can change
        bool modified;

        Rect crop;
        Rect requestedCrop;

        Rect finalCrop;

        // If set, defers this state update until the Layer identified by handle
        // receives a frame with the given frameNumber
        wp<IBinder> handle;
        uint64_t frameNumber;

        // the transparentRegion hint is a bit special, it's latched only
        // when we receive a buffer -- this is because it's "content"
        // dependent.
        Region activeTransparentRegion;
        Region requestedTransparentRegion;
        android_dataspace dataSpace;
    };
	
	/*定义了两个成员*/
    State mDrawingState;//正在使用或者上次使用的状态
    State mCurrentState;//当前或者被修改的状态

比如比较mDrawingState.sequence与mCurrentState.sequence即可知道其属性是否发生变化。

前面提到有多个layer,这些layer在哪个显示器上显示,由什么决定呢?在layer::State.displays与surfaceflinger::State中都存在成员layerStack,当他们中的layerStack相同时,这时才能在显示器上显示。

找到之前surfaceflinger.h

DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;

查看DisplayDeviceState定义:

struct DisplayDeviceState {
        DisplayDeviceState();
        DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure);
        bool isValid() const { return type >= 0; }
        bool isMainDisplay() const { return type == DisplayDevice::DISPLAY_PRIMARY; }
        bool isVirtualDisplay() const { return type >= DisplayDevice::DISPLAY_VIRTUAL; }
        DisplayDevice::DisplayType type;
        sp<IGraphicBufferProducer> surface;
        uint32_t layerStack;
        Rect viewport;
        Rect frame;
        uint8_t orientation;
        uint32_t width, height;
        String8 displayName;
        bool isSecure;
    };

源码分析

进入surfaceflinger.cpp找到void SurfaceFlinger::onMessageReceived(int32_t what) 函数:

void SurfaceFlinger::onMessageReceived(int32_t what) {
	case MessageQueue::INVALIDATE: {
		/*处理各种事物*/
		bool refreshNeeded = handleMessageTransaction();
		/*处理各layer的buffer的更换*/
        refreshNeeded |= handleMessageInvalidate();
        /*发出一个Refresh信号,最终到handleMessageRefresh();函数被调用,我们下小节进行详细的分析*/
        signalRefresh();

其上的handleMessageTransaction与handleMessageInvalidate的时序图如下图所示:
在这里插入图片描述
先来看看handleMessageTransaction函数:

handleMessageTransaction

bool SurfaceFlinger::handleMessageTransaction() {
	handleTransaction(transactionFlags);
		/*其内部会遍历每个layer*/
		handleTransactionLocked(transactionFlags);
			const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
			const sp<Layer>& layer(currentLayers[i]);
    		if (transactionFlags & eTraversalNeeded) 
				/*如果trFlags ==0,则说明目前遍历的这个Layer没有变化*/
				uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
				/*如果layer发生了变化,这调用其中的doTransaction*/
				const uint32_t flags = layer->doTransaction(0);
					/*对Layer中的mDrawingState与mCurrentState进行比较看是否发生了变化*/
					Layer::State c = getCurrentState();
					Layer::State& s(getDrawingState());
					/*代表尺寸是否发生了变化等等,如果发生改变都会去设置相应的标志位*/
					const bool sizeChanged = (c.requested.w != s.requested.w) ||(c.requested.h != s.requested.h);
						
	    			const bool resizePending = (c.requested.w != c.active.w) ||(c.requested.h != c.active.h);		/*该标志位最终返回给调用者const uint32_t flags = layer->doTransaction(0);*/
						flags |= eDontUpdateGeometryState;
				
				/*表示这块区域脏了,以后需要更新他*/
				mVisibleRegionsDirty = true;
			/*内部实现不在此进行粘贴*/
	    	if (transactionFlags & eDisplayTransactionNeeded) {	
	    		// find the displays that were remove, 查找显示器是否被移除
	    		// (ie: in drawing state but not in current state),显示器在drawing state但是不在current state
	    		//...................................
	    	if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
	    		//Layer的角度发生了变化,如旋转了屏幕,Layer会发生一些变化
	    		// The transform hint might have changed for some layers
	    	/*以下为处理surfaceflinger本身的事务*/
	    	if (currentLayers.size() > layers.size())
	    		mVisibleRegionsDirty = true;
	    	/*如果移除设备*/
	    	if (mLayersRemoved) {
			    mLayersRemoved = false;
		        mVisibleRegionsDirty = true;
		        /*Layer的层要相等*/
		        invalidateLayerStack(s.layerStack, visibleReg);
		        	if (hw->getLayerStack() == layerStack) {
           			hw->dirtyRegion.orSelf(dirty);

handleMessageTransaction主要的工作是:
1.遍历每个Layer,执行layer->doTransaction(0),根据其返回值设置mVisibleRegionsDirty(可视区域是否脏,脏了后期需要更新)。
2.处理事务:add/reade/change
3.Layer的角度发生了变化,如旋转了屏幕,Layer会发生一些变化
4.处理surfaceflinger本身的事务,如Layer是否被添加或者删除
总的来看,handleMessageTransaction只是简单的设置了一些标志位。并内有做实质上的工作,下面我们分析handleMessageInvalidate

handleMessageInvalidate

handleMessageInvalidate(使原来的界面数据无效,然后准备新数据),在分析代码的流程时,我们先了解一下buffer有那几种状态:
在这里插入图片描述
上面的生产者对应APP,surfaceflinger代表消费者:
APP需要更新数据的时候,需要从所有free状态的buffe中取出一个buffer,free状态的buffe被取出之后,就变成了DEQUEUED状态,构造好数据之后,在把这个数据放入到队列中,变成了QUEUED状态。
surfaceflinger逍遥消费的时候,就从队列中取出一个buffer,该buffer变成AQUEUED状态,然后进行处理,处理完成之后再把他释放。

bool SurfaceFlinger::handleMessageInvalidate() {
	/*页面切换*/
	handlePageFlip();
		/*首先手机一下需要更新的layer*/
		for (size_t i = 0, count = layers.size(); i<count ; i++) {
			if (layer->hasQueuedFrame()) 
				layersWithQueuedFrames.push_back(layer.get());
		/*对所有需要更新的layer*/
		for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) {	
			/*锁定buffer*/
			const Region dirty(layer->latchBuffer(visibleRegions));
			status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,mLastFrameNumberReceived);
				// Acquire the next buffer,对应前面提到buffer的AQUEUED状态
				err = acquireBufferLocked(&item, computeExpectedPresent(dispSync),maxFrameNumber);
				// Release the previous buffer.
				updateAndReleaseLocked
				/*把bufer绑定到Texture(图形界面处理相关)之中*/
				err = bindTextureImageLocked();

通过上面的流程,其主要工作为:
1.Acquire the next buffer
2.Release the previous buffer
3.bindTextureImageLocked

到这里,我们已经合成了新的数据,之后会通过signalRefresh发出一个信号,导致:

void SurfaceFlinger::onMessageReceived(int32_t what) {
	    case MessageQueue::REFRESH: {
            	handleMessageRefresh();

被执行,小小节在为大家进行讲解。