SurfaceFlinger的commit/handleTransaction分析

整体背景介绍

hi,粉丝朋友们:
大家好!本节我们来讲解一下SurfaceFlinger主要合成工作的第一个阶段任务commit
一般SurfaceFlinger端的合成工作主要有两个
1.commit
主要就是处理app端发起的一系列transaction的事务请求,需要对这些请求进行识别是否当前帧处理,处理过程就是把事务中的属性取出,然后更新到Layer中,偶buffer更新的还需要进行相关的latchbuffer操作
2.composite
主要负责对相关要进行上帧的layer进行,识别排序好,然后合成,有hwc合成的会构建对应OutputLayer传递hwc,GPU合成则直接合成,再传递到hwc中
在这里插入图片描述

commit的数据Transaction部分来源

app跨进程传递Transaction阶段:


status_t SurfaceFlinger::setTransactionState(
        const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states,
        const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
        const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
        bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
        const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
    // 使用传递的参数构建出TransactionState
    TransactionState state{frameTimelineInfo,  states,
                           displays,           flags,
                           applyToken,         inputWindowCommands,
                           desiredPresentTime, isAutoTimestamp,
                           uncacheBuffer,      postTime,
                           permissions,        hasListenerCallbacks,
                           listenerCallbacks,  originPid,
                           originUid,          transactionId};

    // Check for incoming buffer updates and increment the pending buffer count.
    state.traverseStatesWithBuffers([&](const layer_state_t& state) {
        mBufferCountTracker.increment(state.surface->localBinder());//这里会有一个Buffer的计数器,就是systrace看到的BufferTX那一项
    });

    if (mTransactionTracing) {
        mTransactionTracing->addQueuedTransaction(state);
    }
    //这里是真正核心,构建的state放入队列
    queueTransaction(state);

    return NO_ERROR;
}

看看核心方法queueTransaction

void SurfaceFlinger::queueTransaction(TransactionState& state) {
   //最重前面构造的state放入了mTransactionQueue队列
    mTransactionQueue.emplace_back(state);
    ATRACE_INT("TransactionQueue", mTransactionQueue.size());
    const auto frameHint = state.isFrameActive() ? FrameHint::kActive : FrameHint::kNone;
	//调用setTransactionFlags传递是eTransactionFlushNeeded,请求vsync,这个vsync课程已经分析
    setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken, frameHint);
}

在这里插入图片描述
mBufferCountTracker.increment对应systrace的体现:
在这里插入图片描述
这里属于跨进程调用过来就会在这里的上升进行体现,什么时候下降呢?那就是在vsync的 的latchBuffer时候.

应用端跨进程一般是surfacecontrol的apply开始,SurfaceComposerClient::Transaction::apply的作用是将有变动相关的 SurfaceControl 对应的 ComposerState 等打包发送给 SurfaceFlinger。然后这些值会被重新封装到 SurfaceFlinger::TransactionState,并加入到 mTransactionQueue 里。

Vsync到来处理Transaction阶段:

//这里frameTime代表当前时间,expectedVsyncTime代表硬件vsync时间,即屏幕先的vsync时间
bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime)
        FTL_FAKE_GUARD(kMainThreadContext) {
   
    const auto vsyncIn = [&] {
        if (!ATRACE_ENABLED()) return 0.f;
        return (mExpectedPresentTime - systemTime()) / 1e6f;
    }();
    ATRACE_FORMAT("%s %" PRId64 " vsyncIn %.2fms%s", __func__, vsyncId, vsyncIn,
                  mExpectedPresentTime == expectedVsyncTime ? "" : " (adjusted)");
//省略部分

    // Composite if transactions were committed, or if requested by HWC.
    bool mustComposite = mMustComposite.exchange(false);
    {
        ATRACE_NAME("MustComposite");
        mFrameTimeline->setSfWakeUp(vsyncId, frameTime, Fps::fromPeriodNsecs(stats.vsyncPeriod));

        bool needsTraversal = false;
        if (clearTransactionFlags(eTransactionFlushNeeded)) { //满足eTransactionFlushNeeded条件进入
            needsTraversal |= commitCreatedLayers();//负责新创建的layer相关业务处理
            needsTraversal |= flushTransactionQueues(vsyncId);//这里是对前面的Transaction处理的核心部分
        }

        const bool shouldCommit =
                (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
        if (shouldCommit) {
            commitTransactions();//进行Transaction提交主要就是交换mCurrentState和DrawingState
        }

        if (transactionFlushNeeded()) {//判断是否又要启动新vsync信号
            ATRACE_NAME("transactionFlushNeeded");
            setTransactionFlags(eTransactionFlushNeeded);
        }

        mustComposite |= shouldCommit;
        mustComposite |= latchBuffers();//进行核心的latchBuffer

        // This has to be called after latchBuffers because we want to include the layers that have
        // been latched in the commit callback
        if (!needsTraversal) {
            // Invoke empty transaction callbacks early.
            mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
        } else {
            // Invoke OnCommit callbacks.
            mTransactionCallbackInvoker.sendCallbacks(true /* onCommitOnly */);
        }

        updateLayerGeometry();//对要这次vsync显示刷新的layer进行脏区设置
    }
   //省略部分
   //鼠标相关layer处理,我们忽略
    updateCursorAsync();
    updateInputFlinger();//更新触摸input下的相关的window等,这里也非常关键哈,直接影响触摸是否到app

    return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
}

上面这个commit方法干的事情很多,这里总结一下最重要以下几个部分:
1. flushTransactionQueues 对前面app跨进程传递的Transaction处理的核心部分
方法如下:

bool SurfaceFlinger::flushTransactionQueues(int64_t vsyncId) {
    //省略部分
    //刷新一下PendingTransactionQueues,这个主要是上次vsync中没有满足条件的Transaction放入的
            transactionsPendingBarrier =
                    flushPendingTransactionQueues(transactions, bufferLayersReadyToPresent,
                            applyTokensWithUnsignaledTransactions, /*tryApplyUnsignaled*/ true);

//开始遍历当次vsync的mTransactionQueue
            while (!mTransactionQueue.empty()) {
                auto& transaction = mTransactionQueue.front();
                //判断是否处于mPendingTransactionQueues队里里面
                const bool pendingTransactions =
                        mPendingTransactionQueues.find(transaction.applyToken) !=
                        mPendingTransactionQueues.end();
                        //这里有个ready的判断,主要就是看看当前的Transaction是否已经ready,没有ready则不予进行传递Transaction
                const auto ready = [&]() REQUIRES(mStateLock) {
                    if (pendingTransactions) {//如果还存在pending队列直接是notready
                        ATRACE_NAME("pendingTransactions");
                        return TransactionReadiness::NotReady;
                    }

                    return transactionIsReadyToBeApplied(transaction, transaction.frameTimelineInfo,
                                                         transaction.isAutoTimestamp,
                                                         transaction.desiredPresentTime,
                                                         transaction.originUid, transaction.states,
                                                         bufferLayersReadyToPresent,
                                                         transactions.size(),
                                                         /*tryApplyUnsignaled*/ true);
                }();
                if (ready != TransactionReadiness::Ready) {//没有ready的
                    if (ready == TransactionReadiness::NotReadyBarrier) {
                        transactionsPendingBarrier++;
                    }
                    //放入mPendingTransactionQueues
                    mPendingTransactionQueues[transaction.applyToken].push(std::move(transaction));
                } else {
                //已经ready则进入如下的操作
                 transaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
                        const bool frameNumberChanged = state.bufferData->flags.test(
                                BufferData::BufferDataChange::frameNumberChanged);
                                //会把state放入到bufferLayersReadyToPresent这个map中
                        if (frameNumberChanged) { 
                            bufferLayersReadyToPresent[state.surface] = state.bufferData->frameNumber;
                        } else {
                            // Barrier function only used for BBQ which always includes a frame number.
                            // This value only used for barrier logic.
                            bufferLayersReadyToPresent[state.surface] =
                                std::numeric_limits<uint64_t>::max();
                        }
                    });
      				//最重要的放入到transactions
                    transactions.emplace_back(std::move(transaction));
                }
                //从mTransactionQueue这里移除
                mTransactionQueue.pop_front();
                ATRACE_INT("TransactionQueue", mTransactionQueue.size());
            }
//省略部分
			//根据enableLatchUnsignaledConfig属性,不是disabled的话需要对前面的notready情况进行第二次的校验放过
            if (enableLatchUnsignaledConfig != LatchUnsignaledConfig::Disabled) {
                flushUnsignaledPendingTransactionQueues(transactions, bufferLayersReadyToPresent,
                                                        applyTokensWithUnsignaledTransactions);
            }
			//进行关键的applyTransactions操作
            return applyTransactions(transactions, vsyncId);
        }
    }
}

上面基本流程就是遍历mTransactionQueue然后获取都已经Ready的Transaction,然后进行applyTransactions操作。
那么怎么判断是否ready呢?当然就要看关键的transactionIsReadyToBeApplied方法:

auto SurfaceFlinger::transactionIsReadyToBeApplied(TransactionState& transaction,
        const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime,
        uid_t originUid, const Vector<ComposerState>& states,
        const std::unordered_map<
            sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent,
        size_t totalTXapplied, bool tryApplyUnsignaled) const -> TransactionReadiness {
  //省略非关键
    bool fenceUnsignaled = false;
    auto queueProcessTime = systemTime();
    //关键部分对transaction的states进行挨个state遍历情况
    for (const ComposerState& state : states) {
        const layer_state_t& s = state.state;
        //这里会判断到底有没有surface。没有的话就不会进入下面判断环节
 		if (s.surface) {
            layer = fromHandle(s.surface).promote();
        } else if (s.hasBufferChanges()) {
            ALOGW("Transaction with buffer, but no Layer?");
            continue;
        }
        
        //注意这里会有一个标志allowLatchUnsignaled意思是是否可以latch非signaled的buffer
        const bool allowLatchUnsignaled = tryApplyUnsignaled &&
                shouldLatchUnsignaled(layer, s, states.size(), totalTXapplied);
        const bool acquireFenceChanged = s.bufferData &&
                s.bufferData->flags.test(BufferData::BufferDataChange::fenceChanged) &&
                s.bufferData->acquireFence;
         //这里会进行关键的判断,判断state的bufferData->acquireFence是否已经signaled
        fenceUnsignaled = fenceUnsignaled ||
                (acquireFenceChanged &&
                 s.bufferData->acquireFence->getStatus() == Fence::Status::Unsignaled);
		//如果fenceUnsignaled属于fenceUnsignaled,allowLatchUnsignaled也为false
        if (fenceUnsignaled && !allowLatchUnsignaled) {
            //那么就代表不可以传递transaction,会返回NotReady
            ATRACE_NAME("fence unsignaled");
            return TransactionReadiness::NotReady;
        }

        if (s.hasBufferChanges()) {
            // If backpressure is enabled and we already have a buffer to commit, keep the
            // transaction in the queue.
            const bool hasPendingBuffer = bufferLayersReadyToPresent.find(s.surface) !=
                bufferLayersReadyToPresent.end();
                //如果前面已经有state放入了,则不在放入,会放入pending
            if (layer->backpressureEnabled() && hasPendingBuffer && isAutoTimestamp) {
                ATRACE_NAME("hasPendingBuffer");
                return TransactionReadiness::NotReady;
            }
        }
    }
    return fenceUnsignaled ? TransactionReadiness::ReadyUnsignaled : TransactionReadiness::Ready;
}

再接下来看看关键的applyTransactions方法


bool SurfaceFlinger::applyTransactions(std::vector<TransactionState>& transactions,
                                       int64_t vsyncId) {
    ATRACE_CALL();
    bool needsTraversal = false;
    // Now apply all transactions.
    //遍历每一个上面判断为ready的transaction
    for (auto& transaction : transactions) {
    //核心方法又调用到了applyTransactionState
        needsTraversal |=
                applyTransactionState(transaction.frameTimelineInfo, transaction.states,
                                      transaction.displays, transaction.flags,
                                      transaction.inputWindowCommands,
                                      transaction.desiredPresentTime, transaction.isAutoTimestamp,
                                      transaction.buffer, transaction.postTime,
                                      transaction.permissions, transaction.hasListenerCallbacks,
                                      transaction.listenerCallbacks, transaction.originPid,
                                      transaction.originUid, transaction.id);
    
    }

    return needsTraversal;
}


bool SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo,
                                           Vector<ComposerState>& states,
                                           const Vector<DisplayState>& displays, uint32_t flags,
                                           const InputWindowCommands& inputWindowCommands,
                                           const int64_t desiredPresentTime, bool isAutoTimestamp,
                                           const client_cache_t& uncacheBuffer,
                                           const int64_t postTime, uint32_t permissions,
                                           bool hasListenerCallbacks,
                                           const std::vector<ListenerCallbacks>& listenerCallbacks,
                                           int originPid, int originUid, uint64_t transactionId) {
    ATRACE_CALL();
    uint32_t transactionFlags = 0;
    //遍历是transaction的dispplays
    for (const DisplayState& display : displays) {
    	    //遍历是否有dispplay相关的变化
        transactionFlags |= setDisplayStateLocked(display);
    }

    uint32_t clientStateFlags = 0;
    for (int i = 0; i < states.size(); i++) {//最关键方法开始遍历一个个的states
        ComposerState& state = states.editItemAt(i);
        //调用到了setClientStateLocked方法
        clientStateFlags |= setClientStateLocked(frameTimelineInfo, state, desiredPresentTime,
                                                 isAutoTimestamp, postTime, permissions);
        if ((flags & eAnimation) && state.state.surface) {
            if (const auto layer = fromHandle(state.state.surface).promote()) {
                using LayerUpdateType = scheduler::LayerHistory::LayerUpdateType;
                mScheduler->recordLayerHistory(layer.get(),
                                               isAutoTimestamp ? 0 : desiredPresentTime,
                                               LayerUpdateType::AnimationTX);
            }
        }
    }
//省略部分
    return needsTraversal;
}

这里面的关键方法又是setClientStateLocked

uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo& frameTimelineInfo,
                                              ComposerState& composerState,
                                              int64_t desiredPresentTime, bool isAutoTimestamp,
                                              int64_t postTime, uint32_t permissions) {
 //省略部分

    const uint64_t what = s.what;
    uint32_t flags = 0;
    sp<Layer> layer = nullptr;
    if (s.surface) {
        layer = fromHandle(s.surface).promote();
    } else {
        // The client may provide us a null handle. Treat it as if the layer was removed.
        ALOGW("Attempt to set client state with a null layer handle");
    }
//省略其他设置变化部分,只留下一个经典的buffer部分
    if (what & layer_state_t::eBufferChanged) {//如果发现有buffer变化
        std::shared_ptr<renderengine::ExternalTexture> buffer =
                getExternalTextureFromBufferData(*s.bufferData, layer->getDebugName());
              //把state的bufferData相关信息设置到了layer中去
        if (layer->setBuffer(buffer, *s.bufferData, postTime, desiredPresentTime, isAutoTimestamp,
                             dequeueBufferTimestamp, frameTimelineInfo)) {
            flags |= eTraversalNeeded;
        }
    }
    return flags;
}

这里setClientStateLocked就是真正干拷贝活的,相当于终于把app设置在transaction的数据,同步赋值到了surfaceflinger的layer中去了。
到这里flushTransactionQueues就执行完毕,总结他干的活如下:

1、遍历app层面设置过来事务集合mTransactionQueue,检测获取已经ready的transaction

2、针对已经ready的tranactions集合进行appTransactionState,主要就是transaction中包含state的变化部分
全部同步到对应的layer中,包括所有layer的属性变化,buffer变化等都进行同步

2.接下来走到commitTransactions部分

void SurfaceFlinger::commitTransactions() {
  //省略部分
  //最重要调用commitTransactionsLocked方法
    commitTransactionsLocked(clearTransactionFlags(eTransactionMask));

    mDebugInTransaction = 0;
}


void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) {
   //省略一部分非本次重点
//主要调用了doCommitTransactions
    doCommitTransactions();
    signalSynchronousTransactions(CountDownLatch::eSyncTransaction);
    mAnimTransactionPending = false;
}
void SurfaceFlinger::doCommitTransactions() {
    ATRACE_CALL();
//省略
    // If this transaction is part of a window animation then the next frame
    // we composite should be considered an animation as well.
    mAnimCompositionPending = mAnimTransactionPending;
	//最关键mCurrentState赋值给了mDrawingState,
    mDrawingState = mCurrentState;
   //省略部分
}

这里的commitTranstions主要就是把mCurrentState赋值给mDrawingState,这里的State都是SurfaceFlinger层面的,主要保存着各个Layer和Display的信息结构体
这里mDrawingState代表上一次绘制中的State,mCurrentState代表是当前Transaction处理过程中改变的State

这里得说说相关的State区别
Layer中有State和SurfaceFlinger中State对比
Layer中的:


    struct State {
        Geometry active_legacy;
        Geometry requested_legacy;
        int32_t z;

        ui::LayerStack layerStack;

        uint32_t flags;
        uint8_t reserved[2];
        int32_t sequence; // changes when visible regions can change
        bool modified;

        // Crop is expressed in layer space coordinate.
        Rect crop;
        Rect requestedCrop;

        // 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_legacy;
        Region requestedTransparentRegion_legacy;

        LayerMetadata metadata;

        // If non-null, a Surface this Surface's Z-order is interpreted relative to.
        wp<Layer> zOrderRelativeOf;
        bool isRelativeOf{false};

        // A list of surfaces whose Z-order is interpreted relative to ours.
        SortedVector<wp<Layer>> zOrderRelatives;

        half4 color;
        float cornerRadius;
        int backgroundBlurRadius;

        gui::WindowInfo inputInfo;
        wp<Layer> touchableRegionCrop;

        // dataspace is only used by BufferStateLayer and EffectLayer
        ui::Dataspace dataspace;

        // The fields below this point are only used by BufferStateLayer
        uint64_t frameNumber;
        uint32_t width;
        uint32_t height;
        ui::Transform transform;

        uint32_t bufferTransform;
        bool transformToDisplayInverse;

        Region transparentRegionHint;

        std::shared_ptr<renderengine::ExternalTexture> buffer;
        client_cache_t clientCacheId;
        sp<Fence> acquireFence;
        std::shared_ptr<FenceTime> acquireFenceTime;
        HdrMetadata hdrMetadata;
        Region surfaceDamageRegion;
        int32_t api;

        sp<NativeHandle> sidebandStream;
        mat4 colorTransform;
        bool hasColorTransform;

        // pointer to background color layer that, if set, appears below the buffer state layer
        // and the buffer state layer's children.  Z order will be set to
        // INT_MIN
        sp<Layer> bgColorLayer;

        // The deque of callback handles for this frame. The back of the deque contains the most
        // recent callback handle.
        std::deque<sp<CallbackHandle>> callbackHandles;
        bool colorSpaceAgnostic;
        nsecs_t desiredPresentTime = 0;
        bool isAutoTimestamp = true;

        // Length of the cast shadow. If the radius is > 0, a shadow of length shadowRadius will
        // be rendered around the layer.
        float shadowRadius;

        // Layer regions that are made of custom materials, like frosted glass
        std::vector<BlurRegion> blurRegions;

        // Priority of the layer assigned by Window Manager.
        int32_t frameRateSelectionPriority;

        FrameRate frameRate;

        // The combined frame rate of parents / children of this layer
        FrameRate frameRateForLayerTree;

        // Set by window manager indicating the layer and all its children are
        // in a different orientation than the display. The hint suggests that
        // the graphic producers should receive a transform hint as if the
        // display was in this orientation. When the display changes to match
        // the layer orientation, the graphic producer may not need to allocate
        // a buffer of a different size. ui::Transform::ROT_INVALID means the
        // a fixed transform hint is not set.
        ui::Transform::RotationFlags fixedTransformHint;

        // The vsync info that was used to start the transaction
        FrameTimelineInfo frameTimelineInfo;

        // When the transaction was posted
        nsecs_t postTime;

        sp<ITransactionCompletedListener> releaseBufferListener;
        // SurfaceFrame that tracks the timeline of Transactions that contain a Buffer. Only one
        // such SurfaceFrame exists because only one buffer can be presented on the layer per vsync.
        // If multiple buffers are queued, the prior ones will be dropped, along with the
        // SurfaceFrame that's tracking them.
        std::shared_ptr<frametimeline::SurfaceFrame> bufferSurfaceFrameTX;
        // A map of token(frametimelineVsyncId) to the SurfaceFrame that's tracking a transaction
        // that contains the token. Only one SurfaceFrame exisits for transactions that share the
        // same token, unless they are presented in different vsyncs.
        std::unordered_map<int64_t, std::shared_ptr<frametimeline::SurfaceFrame>>
                bufferlessSurfaceFramesTX;
        // An arbitrary threshold for the number of BufferlessSurfaceFrames in the state. Used to
        // trigger a warning if the number of SurfaceFrames crosses the threshold.
        static constexpr uint32_t kStateSurfaceFramesThreshold = 25;

        // Stretch effect to apply to this layer
        StretchEffect stretchEffect;

        // Whether or not this layer is a trusted overlay for input
        bool isTrustedOverlay;

        Rect bufferCrop;
        Rect destinationFrame;

        sp<IBinder> releaseBufferEndpoint;

        gui::DropInputMode dropInputMode;

        bool autoRefresh = false;

        bool dimmingEnabled = true;
    };

SurfaceFlinger中的State:

class State {
    public:
        explicit State(LayerVector::StateSet set) : stateSet(set), layersSortedByZ(set) {}
        State& operator=(const State& other) {
            // We explicitly don't copy stateSet so that, e.g., mDrawingState
            // always uses the Drawing StateSet.
            layersSortedByZ = other.layersSortedByZ;
            displays = other.displays;
            colorMatrixChanged = other.colorMatrixChanged;
            if (colorMatrixChanged) {
                colorMatrix = other.colorMatrix;
            }
            globalShadowSettings = other.globalShadowSettings;

            return *this;
        }

        const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid;
        LayerVector layersSortedByZ;
        DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;

        bool colorMatrixChanged = true;
        mat4 colorMatrix;

        renderengine::ShadowSettings globalShadowSettings;

        void traverse(const LayerVector::Visitor& visitor) const;
        void traverseInZOrder(const LayerVector::Visitor& visitor) const;
        void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const;
    };

看可以看到Layer的State和SurfaceFlinger的State虽然名字一样,但是差异还是很大的:

Layer.State 主要存储了该 Layer 相关的数据,例如长宽,各种矩阵,阴影等

SurfaceFlinger.State 主要存储了当前的所有 Layer 以及 Display 设备,并且提供按照 z 值正序/逆序遍历的方法。

接下来再看看latchBuffer部分


bool SurfaceFlinger::latchBuffers() {
  
    mDrawingState.traverse([&](Layer* layer) {
        if (layer->clearTransactionFlags(eTransactionNeeded) || mForceTransactionDisplayChange) {
            const uint32_t flags = layer->doTransaction(0);//调用doTransaction主要返回flag看看是否有图层显示区域相关变化
            if (flags & Layer::eVisibleRegion) {
                mVisibleRegionsDirty = true;
            }
        }
		//判断是否有buffer
        if (layer->hasReadyFrame()) {
            frameQueued = true;
            //是否应该显示
            if (layer->shouldPresentNow(expectedPresentTime)) {
            //如果要显示放入到mLayersWithQueuedFrames队列
                mLayersWithQueuedFrames.emplace(layer);
            } else {
                ATRACE_NAME("!layer->shouldPresentNow()");
                layer->useEmptyDamage();
            }
        } else {
            layer->useEmptyDamage();
        }
    });
   //上面主要是为了从sf的mDrawingState遍历寻找出有buffer的layer

	//如果buffer队列不为空
    if (!mLayersWithQueuedFrames.empty()) {
        // mStateLock is needed for latchBuffer as LayerRejecter::reject()
        // writes to Layer current state. See also b/119481871
        Mutex::Autolock lock(mStateLock);

        for (const auto& layer : mLayersWithQueuedFrames) {
        //进行关键的latchBuffer操作,然后newDataLatched设置成了true
            if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)) {
                mLayersPendingRefresh.push_back(layer); //这里有latchBuffer说明有buffer刷新,放入mLayersPendingRefresh
                newDataLatched = true;
                ATRACE_FORMAT("latchBuffer layer Name = %s",layer->getDebugName());
            }
            layer->useSurfaceDamage();
        }
    }
     //省略部分
    return !mLayersWithQueuedFrames.empty() && newDataLatched;
}

下面重点看看latchBuffer这个方法:
frameworks/native/services/surfaceflinger/BufferLayer.cpp


bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
                              nsecs_t expectedPresentTime) {
  //省略部分
    // Capture the old state of the layer for comparisons later
    const State& s(getDrawingState());
    const bool oldOpacity = isOpaque(s);

    BufferInfo oldBufferInfo = mBufferInfo;
	//调用到BufferStateLayer中的updateTexImage,这里业务主要返回对应的recomputeVisibleRegions
    status_t err = updateTexImage(recomputeVisibleRegions, latchTime, expectedPresentTime);
  
	//这里主要吧state的相关buffer数据赋值给mBufferInfo
    err = updateActiveBuffer();
  
   //赋值一下framenumber
    err = updateFrameNumber();
   //这里又一次吧mDrawingState中BufferInfo需要的大部分数据进行赋值
    gatherBufferInfo();
//省略

    return true;
}


其实这里的latchBuffer主要还是想把前面Transaction时候赋值到了Layer的mDrawingState和buffer相关的数据赋值到Layer的mBufferInfo中

下面在进入下一个updateLayerGeometry

void SurfaceFlinger::updateLayerGeometry() {
    ATRACE_CALL();

    if (mVisibleRegionsDirty) {
        computeLayerBounds(); //触发各个layer计算对于的bound
    }
	//前面有buffer的集合mLayersPendingRefresh进行对应display的dirtyRegion更新
    for (auto& layer : mLayersPendingRefresh) {
        Region visibleReg;
        visibleReg.set(layer->getScreenBounds());
        invalidateLayerStack(layer, visibleReg);//刷新一下display的dirtyRegion
    }
    mLayersPendingRefresh.clear();
}


void SurfaceFlinger::invalidateLayerStack(const sp<const Layer>& layer, const Region& dirty) {
    for (const auto& [token, displayDevice] : FTL_FAKE_GUARD(mStateLock, mDisplays)) {
        auto display = displayDevice->getCompositionDisplay();
        if (display->includesLayer(layer->getOutputFilter())) {//寻找到对应的display
            display->editState().dirtyRegion.orSelf(dirty);//设置到了display->editState中
        }
    }
}

上面主要就是干了一件事,根据这次有buffer的Layer进行遍历,刷新对应display的dirtyRegion

最后一个关键方法updateInputFlinger
这个其实马哥input专题课程面讲过,新版本有小部分变化

void SurfaceFlinger::updateInputFlinger() {
   
    if (mVisibleRegionsDirty || mInputInfoChanged) {
        mInputInfoChanged = false;
        updateWindowInfo = true;
        //进行遍历整个系统的layer和display转变成windowInfos,displayInfos信息
        buildWindowInfos(windowInfos, displayInfos);
    }
 	//这里放入子线程进行相对应跨进程通讯
    BackgroundExecutor::getInstance().sendCallbacks({[updateWindowInfo,
                                                      windowInfos = std::move(windowInfos),
                                                      displayInfos = std::move(displayInfos),
                                                      inputWindowCommands =
                                                              std::move(mInputWindowCommands),
                                                      inputFlinger = mInputFlinger, this]() {
        if (updateWindowInfo) {
        //这里调用是mWindowInfosListenerInvoker进行的windowInfos, displayInfos进行跨进程传递?
            mWindowInfosListenerInvoker->windowInfosChanged(windowInfos, displayInfos,
                                                            inputWindowCommands.syncInputWindows);
        } 
        for (const auto& focusRequest : inputWindowCommands.focusRequests) {
        //直接调用inputFlinger的bpbinder跨进程设置setFocusedWindow
            inputFlinger->setFocusedWindow(focusRequest);
        }
    }});

    mInputWindowCommands.clear();
}

这里是不是大家有疑问?为啥setFocusedWindow直接跨进程调用inputFlinger->setFocusedWindow
为啥设置windowInfos, displayInfos不直接设置,其实这个也是和之前版本最大的不同
原因如下:
主要是windowInfos, displayInfos信息需要的不仅仅是InputDispatcher,其他也有需要的,所以这里就需要考虑统一这一部分的接口

注意看mWindowInfosListenerInvoker其实可以装载多个listener,即可以实现吧windowInfos, displayInfos通知到多个端

status_t SurfaceFlinger::addWindowInfosListener(
        const sp<IWindowInfosListener>& windowInfosListener) const {
    mWindowInfosListenerInvoker->addWindowInfosListener(windowInfosListener);
    return NO_ERROR;
}

status_t SurfaceFlinger::removeWindowInfosListener(
        const sp<IWindowInfosListener>& windowInfosListener) const {
    mWindowInfosListenerInvoker->removeWindowInfosListener(windowInfosListener);
    return NO_ERROR;
}

比如就有如下2处使用:
在这里插入图片描述

本文章对应视频手把手教你学framework:
hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
在这里插入图片描述

私聊作者+v(androidframework007)

七件套专题:在这里插入图片描述
点击这里 https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频:https://www.bilibili.com/video/BV1wc41117L4/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/301697.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp 微信小程序跳转外部链接

一、背景&#xff1a; 开发小程序时&#xff0c;跳转到内部路径通常会使用&#xff1a;uni.navigateTo&#xff0c;uni.redirectTo&#xff0c;uni.reLaunch&#xff0c;uni.switchTab等方法&#xff0c;可以跳转到pages.json中已经注册的页面 uni.navigateTo(OBJECT) | uni-…

计算机毕业设计-----SSM CRM人事管理系统

项目介绍 CRM人事管理系统&#xff0c;主要功能有&#xff1a; 用户管理&#xff1a;用户查询、添加用户、编辑、删除&#xff1b; 职位管理&#xff1a;职位查询、添加职位、删除&#xff1b; 部门管理&#xff1a;部门查询、添加部门、删除&#xff1b; 员工管理&#xff1…

王者荣耀与元梦之星联名小乔皮肤即将下架!

即将下架&#xff01;几款皮肤你还不知道的&#xff0c;推荐一起看看&#xff01; 元梦之星即将下架皮肤&#xff1b;小乔、宝拉、小爱、大魔术师尼克。 小乔截止日期&#xff1a;2024年1.5日23.59正式下架 灵魂歌姬宝拉截止日期&#xff1a;2024年1.11日23.59正式下架 小爱…

Mysql死锁问题Deadlock found when trying to get lock;try restarting transaction

一、问题描述 今天测试在测试环境做压测&#xff0c;发现了一个报错&#xff0c;来找我帮忙看&#xff0c;如下图&#xff1a; 二、问题排查 先去服务器上&#xff0c;看看死锁的日志&#xff0c;找到 mysql 的安装路径&#xff0c;使用如下命令登录 mysql mysql -h 数据库IP…

计算机毕业设计-----ssm知识库管理系统

项目介绍 文件集中上传&#xff1a;系统支持单文件上传以及批量上传&#xff0c;系统支持zip、rar格式的压缩包导入。亮点创新 多格式文件在线预览 用户可以对所有公共文件进行浏览&#xff0c;支持office&#xff0c;pdf格式以及常见图片格式&#xff0c;音频格式&#xff0c…

BOM,JS执行机制等

1.BOM 概述 1.1什么是 BOM BOM( Browser Object Model &#xff09;即浏览器对象模型&#xff0c;它提供了独立于内容而与浏览器窗口进行交互的对象&#xff0c;其核心对象是window. BOM由一系列相关的对象构成&#xff0c;并且每个对象都提供了很多方法与属性。 BOM缺乏标…

基于ssm的孩童收养信息管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本孩童收养信息管理就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

二叉树的深度和高度问题(算法村第八关白银挑战)

二叉树的最大深度 104. 二叉树的最大深度 - 力扣&#xff08;LeetCode&#xff09; 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null…

揭开JavaScript数据类型的神秘面纱

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ ✨ 前言 JavaScript作为一门动态类型语言,其数据类型一直是开发者们关注的话题。本文将深入探讨Jav…

创建K8s节点的虚拟机

1、点击“创建新的虚拟机” 2、选择自定义&#xff0c;点击“下一步” 3、默认&#xff0c;点击“下一步” 4、默认&#xff0c;点击“下一步” 5、默认&#xff0c;点击“下一步” 6、设置虚拟机名称和位置&#xff0c;点击“下一步” 7、点击“下一步” 8、设置2048MB&#x…

x-cmd pkg | gitui - git 终端交互式命令行工具

目录 简介首次用户功能特点类似工具与竞品进一步探索 简介 gitui 由 Stephan D 于 2020 年使用 Rust 语言构建的 git 终端交互式命令行工具&#xff0c;旨在终端界面中便捷管理 git 存储库。 首次用户 使用 x gitui 即可自动下载并使用 在终端运行 eval "$(curl https:/…

C语言动态内存管理

我们目前知道的开辟内存空间的方法有&#xff1a; 1.创建变量 2.创建数组&#xff1b; 但是这2种方法开辟的空间大小都是固定的&#xff0c;如果是数组的话确认了大小之后是无法改变的&#xff1b; int a10;//在栈区空间上开辟4个字节的空间&#xff1b;int arr[10];//在栈…

【每日一题】回旋镖的数量

文章目录 Tag题目来源解题思路方法一&#xff1a;组合数学 写在最后 Tag 【组合数学】【数组】【2024-01-08】 题目来源 447. 回旋镖的数量 解题思路 方法一&#xff1a;组合数学 思路 以数组 points 中的每一个为回旋镖的中心 i&#xff0c;在数组 points 中找距离中心 i…

leetcode:滑动窗口

目录 1.定长滑动窗口 1.1 几乎唯一子数组的最大和(使用map来计数) 1.2 长度为k子数组中的最大和 2.不定长滑动窗口 2.1 最多k个重复元素的最长子数组 2.2 绝对差不超过限制的最长连续子数组(multiset&#xff09; 2.3 将x减到0的最小操作数(正难则反 逆向思维) 2.4 统计…

Windows Server 2003 (NT 5.2.3790.0) 构建指南

Windows Server 2003 (NT 5.2.3790.0) 构建指南 版本 10b&#xff0c;最后更新于 2021/10/21 原文 https://rentry.co/build-win2k3 指令在 XP SP3 x86、Win7 SP1 x86/x64 和 Win10 x64 下测试&#xff0c;结果在其他操作系统下可能会有所不同。 该指南由一位无名的匿名人士维…

每日算法打卡:子矩阵的和 day 8

文章目录 原题链接题目描述输入格式输出格式数据范围输入样例&#xff1a;输出样例&#xff1a; 题目分析示例代码 原题链接 796. 子矩阵的和 题目难度&#xff1a;简单 题目描述 输入一个 n 行 m 列的整数矩阵&#xff0c;再输入 q 个询问&#xff0c;每个询问包含四个整数…

6.综合案例

1. 需求描述 1.1 显示所有员工信息 URI:emps 请求方式:GET 显示效果 1.2 添加操作- 去往添加页面 显示添加页面: URI:emp 请求方式:GET 显示效果 1.3 添加操作- 添加员工 添加员工信息: URI:emp 请求方式:POST 显示效果:完成添加, 重定向到 list 页面。 1.4…

.NET国产化改造探索(四)、银河麒麟安装Nginx

随着时代的发展以及近年来信创工作和…废话就不多说了&#xff0c;这个系列就是为.NET遇到国产化需求的一个闭坑系列。接下来&#xff0c;看操作。 上一篇介绍了如何在银河麒麟操作系统上安装.NET运行环境&#xff0c;这篇文章详细介绍下在银河麒麟操作系统上安装Nginx。 安装…

Unity C# 枚举多选

枚举多选 &#x1f96a;例子&#x1f354;判断 &#x1f96a;例子 [System.Flags]public enum TestEnum{ None 0,Rooms 1 << 1,Walls1<<2,Objects1<<3,Slabs 1 << 4,All Rooms|Walls|Objects|Slabs}&#x1f354;判断 TestEnum test TestEnum.R…

全网最全Midjourney以图生图的详细教程 内有6种案例 小白必收藏!!!!

手把手教你入门绘图超强的AI绘画程序&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画。给大家带来了全新保姆级教程资料包&#xff08;文末可获取&#xff09; 基础介绍 本篇文章&#xff0c;将介绍如何利用Midjourney完成图生图的方式&#xf…