SurfaceFlinger的commit/handleTransaction分析

news2024/11/27 4:41:30

整体背景介绍

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/

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python笔记03-判断和循环

文章目录 比较运算符if-else语句while语句for循环循环中断 比较运算符 字面量True表示真&#xff0c;字面量False表示假 if-else语句 if语句判断条件的结果一定要是布尔类型 不要忘记判断条件后的&#xff1a; 归属于if语句的代码块&#xff0c;需在前方填充4个空格缩进 age…

Python武器库开发-武器库篇之C段扫描器开发(四十三)

Python武器库开发-武器库篇之C段扫描器开发(四十三) 在我们进行渗透过程中的信息收集的步骤时&#xff0c;收集资产目标的C段也是非常重要的一部分。 C段是指互联网中的一类IP地址。IP地址是互联网上每台设备的唯一标识符。IP地址由一系列数字组成&#xff0c;通常以点分十进…

性能分析与调优: Linux 实现 CPU剖析与火焰图

目录 一、实验 1.环境 2.CPU 剖析 3.CPU火焰图 一、实验 1.环境 &#xff08;1&#xff09;主机 表1-1 主机 主机架构组件IP备注prometheus 监测 系统 prometheus、node_exporter 192.168.204.18grafana监测GUIgrafana192.168.204.19agent 监测 主机 node_exporter192…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -全局异常统一处理实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

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

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

Python库中关于时间的常见操作

目录 导入所需的库 获取当前时间 格式化日期和时间 解析日期和时间字符串 时间戳操作 获取当前时间戳&#xff1a; 将时间戳转换为日期和时间&#xff1a; 时间差操作 时间日期的时区处理 时间日期的随机生成 注意事项 总结 在Python中&#xff0c;时间处理是一个重…

ppTinyPose的C++部署(jetson)

文章目录 环境准备硬件软件修改代码编译和运行运行结果参考环境准备 硬件 Jetson AGX Orin 64GB 软件 gcc/g++ >= 5.4(推荐8.2)cmake >= 3.10.0jetpack >= 4.6.1如果需要集成Paddle Inference后端,在Paddle Inference预编译库页面根据开发环境选择对应的Jetpack C…

7.数据转换、格式化、校验

日期字符串格式的表单参数,提交后转换为 Date 类型 <!-- 解决问题: 1.数据类型转换 2.数据格式 3.数据校验 --> BirthDay :<form:input path="birthDay"/>Employee 类中增加日期类型属性: //关于类型转换 private Date birthDay ;数据绑定流程原理 …

快麦ERP退货借助APPlink快速同步CRM

什么是APPlink&#xff1f; APPlink是RestCloud打造的一款简单易用的零代码自动化集成平台&#xff0c;为业务流程提供自动化的解决方案&#xff0c;将企业内部的核心系统以及第三方应用程序和云服务等进行集成。无论是开发人员还是业务人员&#xff0c;都可以使用APPlink轻松…

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

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

科技助力教育:数字化如何改变家校社协同育人?

近年来,随着社会的快速发展,教育的责任已不再仅局限于学校。家庭、学校和社会协同育人理念,正成为促进教育高质量发展的关键要素。 2023年初,教育部等十三部门联合印发《关于健全学校家庭社会协同育人机制的意见》,提出到“十四五”时期末,形成更加完善的由“学校积极主导、家…

山西电力市场日前价格预测【2024-01-09】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2024-01-09&#xff09;山西电力市场全天平均日前电价为314.92元/MWh。其中&#xff0c;最高日前电价为593.66元/MWh&#xff0c;预计出现在18:15。最低日前电价为54.95元/MWh&#xff0c;预计出…

树莓派3B+ /+ CSI摄像头 + FFmpeg + SRS 实现直播推流

简介&#xff1a; 手头有一个树莓派3B 和一块CSI摄像头&#xff0c;想要实现一个推拉流直播的效果。 所需材料&#xff1a;开发板&#xff08;我用的是树莓派3B&#xff09;、CIS摄像头、云服务器&#xff08;用来搭建SRS服务器&#xff09; 具体实现思路&#xff1a; 使用…

看图识熊(四)

概述 人工智能已经快要进入应用的高峰期了&#xff0c;但并不需要每个人都学习算法、建模。对于程序员来说&#xff0c;应该先从自己会的方向入手&#xff0c;学习如何应用AI来解决问题&#xff0c;开发应用。 本文将带着大家动手&#xff0c;从头做一个看图识熊的应用&#…

PyTorch数据并行(DP/DDP)浅析

一直以来都是用的单机单卡训练模型&#xff0c;虽然很多情况下已经足够了&#xff0c;但总有一些情况得上分布式训练&#xff1a; 模型大到一张卡放不下&#xff1b;单张卡batch size不敢设太大&#xff0c;训练速度慢&#xff1b;当你有好几张卡&#xff0c;不想浪费&#xf…

校园跑腿小程序(前后端已完成)可做项目,可当毕设,支持二创

此小程序为我单独在小程序上运行的结果&#xff0c;图片信息、列表信息等没有出现是因为服务器到期了&#xff0c;资源被释放了&#xff0c;无法显示。但是后端是已经实现了的&#xff0c;有兴趣的同学可以私聊我。 效果预览

软件系统设计开发规程

软件设计开发规程目的在于为需求设计、开发、实现解决方案。根据适当情况&#xff0c;解决方案、设计和实现包括单独的产品、产品组件以及产品相关的生命周期的过程&#xff0c;或者它们的组合&#xff0c;以及包括如何利用准则进行接口设计。 技术解决方案过程包括&#xff1a…

工作组,本地用户,资源共享--windows sever 2012 r2

1.建立2个用户&#xff1a;stu1,stu2&#xff0c;stu2第一次登陆必须修改密码 2.建立2个用户&#xff1a;zhangsan,lisi 3.删除stu1 4.修改zhangsan的密码为111111 5.修改lisi的名字为wangwu 6.修改wangwu的密码为222222 7.禁用王五的账号 8.建立2个组&#xff1a;class1,class…

Docker Compose--部署SpringBoot项目--实战

原文网址&#xff1a;Docker Compose--部署SpringBoot项目--实战-CSDN博客 简介 本文用实战介绍Docker Compose部署SpringBoot项目。 ----------------------------------------------------------------------------------------------- 分享Java真实高频面试题&#xff0c…

VMware Workstation——安装VMware Workstation Pro 17

目录 一、下载 二、安装 1、双击安装 2、安装向导 3、最终用户许可协议 4、自定义安装 5、用户体验设置 6、快捷方式 7、准备升级 8、正在安装 9、安装完成 10、输入许可证密钥 11、激活成功 12、桌面图标 一、下载 下载 VMware Workstation Pro 二、安装 1、双…