SurfaceFlinger 合成(8)

SurfaceFlinger 合成

简介

本节会来介绍SurfaceFlinger的核心函数:合成,这个也是SurfaceFLinger最重要的功能之一。
前面我们介绍过应用的窗口怎么把图元Buffer,窗口属性传递给SurfaceFlinger,而SurfaceFlinger就是要讲这些信息整合在一起,然后讲各个应用的窗口全部都合成一个,最后送到drm驱动中去显示。
这个过程有大量计算机图像绘制使用的变量,还有一些gles的使用,有的我们会简单提一下,不关心的可以跳过这些,看一下总体的流程。
接下来,我们就接着VSync信号那章3.8节,SurfaceFlinger收到VSync信号后开始学习。

SurfaceFlinger 处理VSync信号

这里compositor就是SurfaceFlinger

void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId,
                          TimePoint expectedVsyncTime) {
    const TimePoint frameTime = SchedulerClock::now();
    // 做合成的一些预处理,判断flag决策是否需要合成,详见1.1
    if (!compositor.commit(frameTime, vsyncId, expectedVsyncTime)) {
        return;
    }
    // 触发合成。详见2.1
    compositor.composite(frameTime, vsyncId);
    compositor.sample();
}

SurfaceFlinger::commit

在这里插入图片描述

1.1 SurfaceFlinger::commit
数据预处理,判断是否需要进行合成。

bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expectedVsyncTime)
        FTL_FAKE_GUARD(kMainThreadContext) {
    // 这里expectedVsyncTime一般是未来的时间,而frameTime之前传的是now
    // 如果expectedVsyncTime > frameTime,一般是正常情况,直接使用expectedVsyncTime作为预期时间,否则一般是帧延迟了,重新算一个VSync时间。
    const TimePoint lastScheduledPresentTime = mScheduledPresentTime;
    mScheduledPresentTime = expectedVsyncTime;
    mExpectedPresentTime = expectedVsyncTime >= frameTime ? expectedVsyncTime
                                                        : calculateExpectedPresentTime(frameTime);


    const Period vsyncPeriod = mScheduler->getVsyncSchedule()->period();
    // 获取上一帧合成的fence,每次提交合成后会存一个fence到mPreviousPresentFences数组变量里。
    const FenceTimePtr& previousPresentFence = getPreviousPresentFence(frameTime, vsyncPeriod);

    // backpressure propagation模式下,Fence没有好,我们可以适当延迟等待,而不是直接放弃当前帧
    const int graceTimeForPresentFenceMs = static_cast<int>(
            mBackpressureGpuComposition || !mCompositionCoverage.test(CompositionCoverage::Gpu));
    // isFencePending会调用fence wait判断上一帧合成是否完成。
    // 之前提过,fence是跨越设备的锁,我们在上一次合成中只是向gpu或者hwc发送了指令,通过fence可以确定他们是否完成了任务
    // 之前,如果上一帧fence还没有释放,这里会返回false
    const TracedOrdinal<bool> framePending = {"PrevFramePending",
                                            isFencePending(previousPresentFence,
                                                            graceTimeForPresentFenceMs)};

    // 这里的逻辑是同于统计丢帧
    const nsecs_t frameMissedSlop = vsyncPeriod.ns() / 2;
    const nsecs_t previousPresentTime = previousPresentFence->getSignalTime();
    // 如果上一帧fence还没释放,或者上一次完成的时间远大于上一次VSync预期的时间,我们都认为是丢帧了。
    const TracedOrdinal<bool> frameMissed = {"PrevFrameMissed",
                                            framePending ||
                                                    (previousPresentTime >= 0 &&
                                                    (lastScheduledPresentTime.ns() <
                                                    previousPresentTime - frameMissedSlop))};
    // 是否是hwc合成丢帧
    const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
                                                frameMissed &&
                                                        mCompositionCoverage.test(
                                                                CompositionCoverage::Hwc)};
    // 是否是SurfaceFlinger丢帧
    const TracedOrdinal<bool> gpuFrameMissed = {"PrevGpuFrameMissed",
                                                frameMissed &&
                                                        mCompositionCoverage.test(
                                                                CompositionCoverage::Gpu)};
    // 根据前面的判断加一下计数
    if (frameMissed) {
        mFrameMissedCount++;
        mTimeStats->incrementMissedFrames();
    }

    if (hwcFrameMissed) {
        mHwcFrameMissedCount++;
    }

    if (gpuFrameMissed) {
        mGpuFrameMissedCount++;
    }

    if (mTracingEnabledChanged) {
        mLayerTracingEnabled = mLayerTracing.isEnabled();
        mTracingEnabledChanged = false;
    }

    // 如果是需要更新刷新率模式,上一次合成没完成,就直接等下一个VSync再处理。
    if (mSetActiveModePending) {
        if (framePending) {
            mScheduler->scheduleFrame();
            return false;
        }

        // 更新刷新率模式
        mSetActiveModePending = false;
        {
            Mutex::Autolock lock(mStateLock);
            updateInternalStateWithChangedMode();
        }
    }
    // backpressure propagation前面已经有延迟依旧没有完成,那只能请求下一帧VSync再进行合成。
    if (framePending) {
        if (mBackpressureGpuComposition || (hwcFrameMissed && !gpuFrameMissed)) {
            scheduleCommit(FrameHint::kNone);
            return false;
        }
    }

    // 。。。每次commit和composite都会通过PowerAdvisor记录一些时间信息,应该是用作功耗统计使用

    // 开发者模式里显示刷新率的逻辑
    if (mRefreshRateOverlaySpinner) {
        Mutex::Autolock lock(mStateLock);
        if (const auto display = getDefaultDisplayDeviceLocked()) {
            display->animateRefreshRateOverlay();
        }
    }

    // 判断是否需要composite
    bool mustComposite = mMustComposite.exchange(false);
    {
        mFrameTimeline->setSfWakeUp(vsyncId.value, frameTime.ns(),
                                    Fps::fromPeriodNsecs(vsyncPeriod.ns()));
        // 检测Flag来决定是否需要调用flushLifecycleUpdates
        // 在Transaction的章节里我们提过,当通过binder把Transaction传给SurfaceFlinger后,SurfaceFlinger会封装参数后放入一个队列中
        // flushLifecycleUpdates就是去处理队列的时机
        // 主要是将ready的TransactionState和之前收到请求需要添加以及销毁窗口的信息都封装到Update对象内,详见1.2
        const bool flushTransactions = clearTransactionFlags(eTransactionFlushNeeded);
        frontend::Update updates;
        if (flushTransactions) {
            updates = flushLifecycleUpdates();
            //。。。tracing
        }
        bool transactionsAreEmpty;
        // mLegacyFrontEndEnabled和mLayerLifecycleManagerEnabled只有一个为ture,应该是两套算法逻辑,会根据一个系统属性来决定,都是更新layer中的Snapshot的
        // 因为我看我的手机的属性应该是走的mLegacyFrontEndEnabled true的逻辑,我们这里就看这条线,详见1.3
        if (mLegacyFrontEndEnabled) {
            mustComposite |= updateLayerSnapshotsLegacy(vsyncId, updates, flushTransactions,
                                                        transactionsAreEmpty);
        }
        if (mLayerLifecycleManagerEnabled) {
            mustComposite |=
                    updateLayerSnapshots(vsyncId, updates, flushTransactions, transactionsAreEmpty);
        }

        if (transactionFlushNeeded()) {
            setTransactionFlags(eTransactionFlushNeeded);
        }

        // 回调通知,在releasePendingBuffer时候,会addCallbackHandles,然后这里会回调client侧,然后client进行BufferRelease
        if (transactionsAreEmpty) {
            mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
        } else {
            mTransactionCallbackInvoker.sendCallbacks(true /* onCommitOnly */);
        }
    }

    // 处理刷新率更新
    {
        Mutex::Autolock lock(mStateLock);
        mScheduler->chooseRefreshRateForContent();
        setActiveModeInHwcIfNeeded();
    }

    updateCursorAsync();
    // 更新inputFlinger focused窗口
    updateInputFlinger(vsyncId, frameTime);
    // 。。。

    persistDisplayBrightness(mustComposite);
    // 返回是否需要合成
    return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
}

1.2 SurfaceFlinger::flushLifecycleUpdates
这里其实没有真的去处理这些TransactionState,只是将已经处于Ready状态的Transaction都存到update.transactions里
同时会讲之前存在mNewLayers,mCreatedLayers里需要添加或者mDestroyedHandles需要删除的窗口也封装到update里。
这样窗口的变化信息都在update里了。

frontend::Update SurfaceFlinger::flushLifecycleUpdates() {
    frontend::Update update;
    // 处理之前setTransactionState放入队列的任务
    // 会把所有Ready状态到TransactionState返回回来,然后存在update.transactions,详见1.2.1
    update.transactions = mTransactionHandler.flushTransactions();
    {
        // 当client侧通过binder请求SurfaceFlinger,SurfaceFlinger会将参数放到mNewLayers,mCreatedLayers里,这个在SurfaceFlinger binder框架2.2节提到过
        // 这里会把参数都提取出来,全部都放到Update里面
        std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
        update.layerCreatedStates = std::move(mCreatedLayers);
        mCreatedLayers.clear();
        update.newLayers = std::move(mNewLayers);
        mNewLayers.clear();
        update.layerCreationArgs = std::move(mNewLayerArgs);
        mNewLayerArgs.clear();
        update.destroyedHandles = std::move(mDestroyedHandles);
        mDestroyedHandles.clear();
    }
    return update;
}

1.2.1 TransactionHandler::flushTransactions
这里mLocklessTransactionQueue是之前Transaction章节提到的SurfaceFlinger通过queueTransaction放入队列的TransactionState对象。
这里把队列的对象都取出来,存到mPendingTransactionQueues这个map里,这个map的key是窗口的token,value是TransactionState队列。
然后循环调用flushPendingTransactionQueues,flushPendingTransactionQueues本身就会遍历所有的TransactionState,这里之所以还要加一个循环是因为有屏障逻辑。
在acquireNextBufferLocked的时候如果没有立刻将Transaction传给SurfaceFlinger的情况,就会设置一个barrier,表示新的这个Transaction的处理必须要依赖上一个Transaction的完成。
所以这里flushPendingTransactionQueues即使遍历了所有的窗口,也不一定能一次性完成,需要到没有更多可以处理的TransactionState才算完成。
所有Ready的TransactionState在flushPendingTransactionQueues过程中都会被存储到transactions中最后作为返回值返回。

std::vector<TransactionState> TransactionHandler::flushTransactions() {
    while (!mLocklessTransactionQueue.isEmpty()) {
        // 之前讲Transaction到章节最后我们提到,Transaction里面的内容被封装成TransactionState,通过queueTransaction放到队列中
        // 就是放在了mLocklessTransactionQueue中
        // 这里取出来的就是TransactionState
        auto maybeTransaction = mLocklessTransactionQueue.pop();
        // 过滤异常的State
        if (!maybeTransaction.has_value()) {
            break;
        }
        auto transaction = maybeTransaction.value();
        // 把有效都TransactionState放到mPendingTransactionQueues中。
        // mPendingTransactionQueues是一个map,key是窗口token,value是TransactionState队列,
        mPendingTransactionQueues[transaction.applyToken].emplace(std::move(transaction));
    }

    std::vector<TransactionState> transactions;
    TransactionFlushState flushState;
    flushState.queueProcessTime = systemTime();
    // 循环执行flushPendingTransactionQueues,这里需要循环的原因上面已经说了,主要是处理有barrier的Transaction。
    int lastTransactionsPendingBarrier = 0;
    int transactionsPendingBarrier = 0;
    do {
        // 这里比较两次flushPendingTransactionQueues后由于barrier未就绪的Transaction个数,如果一样说明不需要再继续执行flushPendingTransactionQueues
        lastTransactionsPendingBarrier = transactionsPendingBarrier;
        // 会把所有ready状态的TransactionState存储到transactions,详见1.2.2
        transactionsPendingBarrier = flushPendingTransactionQueues(transactions, flushState);
    } while (lastTransactionsPendingBarrier != transactionsPendingBarrier);

    applyUnsignaledBufferTransaction(transactions, flushState);

    mPendingTransactionCount.fetch_sub(transactions.size());
    ATRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load()));
    return transactions;
}

1.2.2 TransactionHandler::flushPendingTransactionQueues
通过applyFilters逐个判断TrasactionState是否ready,主要是判断两个点:
1.时间, 通过SurfaceFlinger::transactionReadyTimelineCheck判断
2.barrier是否就绪,通过SurfaceFlinger::transactionReadyBufferCheck判断
这里就不详细看了,感兴趣可以自己去看下。把ready的TransactionState都存储到transactions里。

int TransactionHandler::flushPendingTransactionQueues
(std::vector<TransactionState>& transactions,
                                                        TransactionFlushState& flushState) {
        int transactionsPendingBarrier = 0;
        // 遍历所有TransactionState
        auto it = mPendingTransactionQueues.begin();
        while (it != mPendingTransactionQueues.end()) {
            auto& [applyToken, queue] = *it;
            while (!queue.empty()) {
                auto& transaction = queue.front();
                flushState.transaction = &transaction;
                // 判断Transaction当前是否ready,比如有barrier的,依赖的前置Transaction是否已经执行了
                // 或者是期望的时间还没有到
                auto ready = applyFilters(flushState);
                if (ready == TransactionReadiness::NotReadyBarrier) {
                    // 统计barrier没有就绪的个数,如果两次循环执行flushPendingTransactionQueues这个数量未改变,就不用再继续循环了,需要等下一帧再处理
                    transactionsPendingBarrier++;
                    break;
                } else if (ready == TransactionReadiness::NotReady) {
                    break;
                } else if (ready == TransactionReadiness::NotReadyUnsignaled) {
                    flushState.queueWithUnsignaledBuffer = applyToken;
                    break;
                }
                // 走到这的Transaction就是已经处于ready状态了,详见1.2.3
                popTransactionFromPending(transactions, flushState, queue);
            }

            if (queue.empty()) {
                it = mPendingTransactionQueues.erase(it);
            } else {
                it = std::next(it, 1);
            }
        }
        // 返回由于barrier未就绪导致未处理的Transcaion个数
        return transactionsPendingBarrier;
    }

1.2.3 TransactionHandler::popTransactionFromPending
将TransactionState加到transactions队列里,然后如果有必要就更新了flushState.bufferLayersReadyToPresent里面窗口对应的frameNumber。

void TransactionHandler::popTransactionFromPending(std::vector<TransactionState>& transactions,
                                                TransactionFlushState& flushState,
                                                std::queue<TransactionState>& queue) {
    auto& transaction = queue.front();
    // Transaction is ready move it from the pending queue.
    flushState.firstTransaction = false;
    removeFromStalledTransactions(transaction.id);
    // 将TransactionState加到transactions队列里。
    transactions.emplace_back(std::move(transaction));
    queue.pop();

    auto& readyToApplyTransaction = transactions.back();
    readyToApplyTransaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
        const bool frameNumberChanged =
                state.bufferData->flags.test(BufferData::BufferDataChange::frameNumberChanged);
        // bufferLayersReadyToPresent是一个map,key是窗口的handle,value是帧号。
        if (frameNumberChanged) {
            flushState.bufferLayersReadyToPresent.emplace_or_replace(state.surface.get(),
                                                                    state.bufferData->frameNumber);
        } else {
            flushState.bufferLayersReadyToPresent
                    .emplace_or_replace(state.surface.get(), std::numeric_limits<uint64_t>::max());
        }
    });
}

1.3 SurfaceFlinger::updateLayerSnapshotsLegacy
这个方法是commit的关键方法,会调用commitCreatedLayers处理添加layer的请求
调用applyTransactions处理通过Transactions请求layer的属性变化
通过调用commitTransactions,处理一些存储在pengding变量里的layer增删操作旋转等,还会将我们前面存储在临时变量的属性(比如mCurrentState)同步到当前使用的属性中去(比如mDrawingState)
最终还调用了latchBuffers去获取了所有新的buffer(如果layer有内容更新则需要获取新buffer),存到BufferInfo中。

bool SurfaceFlinger::updateLayerSnapshotsLegacy(VsyncId vsyncId, frontend::Update& update,
                                                bool transactionsFlushed,
                 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值