Android图形框架之SurfaceComposerClient 提交事务过程

0 前言

Android图形框架之SurfaceControl 构建过程分析一文中,我们了解到了创建一个SurfaceControl的过程,其实这个过程创建了一个Surface以及一个Layer。接下来将根据SurfaceControl构建事务对象并提交。本文将分析下面这段代码:

cpp 复制代码
SurfaceComposerClient::Transaction{}
            .setLayer(surfaceControl, std::numeric_limits<int32_t>::max())
            .show(surfaceControl)
            .setBackgroundColor(surfaceControl, half3{0, 0, 0}, 1.0f, ui::Dataspace::UNKNOWN) // black background
            .setAlpha(surfaceControl, 1.0f)
            .setLayerStack(surfaceControl, ui::LayerStack::fromValue(mLayerStack))
            .apply();

1 Transaction类

SurfaceComposerClient::Transaction{}表示创建了一个Transaction对象。SurfaceComposerClient::Transaction类是Android操作系统中用于管理SurfaceControl的类。它提供了一系列的函数来设置SurfaceControl的各种属性,并将这些更改作为事务对象提交给SurfaceFlinger。下面是它的部分定义代码:

cpp 复制代码
class Transaction : public Parcelable {
    private:
        static sp<IBinder> sApplyToken;
        void releaseBufferIfOverwriting(const layer_state_t& state);
        static void mergeFrameTimelineInfo(FrameTimelineInfo& t, const FrameTimelineInfo& other);
        static void clearFrameTimelineInfo(FrameTimelineInfo& t);
    public:
        status_t writeToParcel(Parcel* parcel) const override;
        status_t readFromParcel(const Parcel* parcel) override;
        void clear();
        Transaction& setLayer(const sp<SurfaceControl>& sc,
                int32_t z);
        Transaction& show(const sp<SurfaceControl>& sc);
        Transaction& setBackgroundColor(const sp<SurfaceControl>& sc, const half3& color,
                                        float alpha, ui::Dataspace dataspace);
        Transaction& setAlpha(const sp<SurfaceControl>& sc,
                float alpha);
        Transaction& setLayerStack(const sp<SurfaceControl>&, ui::LayerStack);
        status_t apply(bool synchronous = false, bool oneWay = false);
        
        ...

从类的定义可以看到,Transaction继承了Parcelable接口,这意味着它可以被序列化和反序列化,方便进行跨进程通信。

2 setLayer函数

cpp 复制代码
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(
        const sp<SurfaceControl>& sc, int32_t z) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    s->what |= layer_state_t::eLayerChanged;
    s->what &= ~layer_state_t::eRelativeLayerChanged;
    s->z = z;

    registerSurfaceControlForCallback(sc);
    return *this;
}

setLayer函数主要完成两个功能:一是调用getLayerState获取Layer的state,二是设置Layer的z值。

我们先来看看getLayerState函数的具体实现:

cpp 复制代码
layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) {
    auto handle = sc->getLayerStateHandle();

    if (mComposerStates.count(handle) == 0) {
        // we don't have it, add an initialized layer_state to our list
        ComposerState s;

        s.state.surface = handle;
        s.state.layerId = sc->getLayerId();

        mComposerStates[handle] = s;
    }

    return &(mComposerStates[handle].state);
}

getLayerState函数首先会通过getLayerStateHandle方法拿到该Layer的stateHandle,实际上就是一个sp<IBinder>。如果它不在mComposerStates里面,则根据stateHandle和LayerId来构建一个新的ComposerState。mComposerStates的定义是std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> mComposerStates,一个sp对应一个ComposerState。最后返回ComposerState类的内部变量state(layer_state_t结构体)。

拿到该Layer的state后,再设置layer_state_t 结构体中的 what 字段的 eLayerChanged 标志位,以及清除 what 字段的 eRelativeLayerChanged 标志位。最后设置z值,它用来表示Surface的层级,z越大表示Surface越靠上层。我们在引言中的代码将z设为最大值,说明该Layer会堆叠显示在最上层。

cpp 复制代码
    s->what |= layer_state_t::eLayerChanged;
    s->what &= ~layer_state_t::eRelativeLayerChanged;
    s->z = z;

3 show函数

cpp 复制代码
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::show(
        const sp<SurfaceControl>& sc) {
    return setFlags(sc, 0, layer_state_t::eLayerHidden);
}

show方法内部调用了setFlags函数,该函数用于清除eLayerHidden标志位,目的是让Surface状态改为显示而不是隐藏。看一看setFlags函数的具体实现:

cpp 复制代码
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags(
        const sp<SurfaceControl>& sc, uint32_t flags,
        uint32_t mask) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||
        (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) ||
        (mask & layer_state_t::eEnableBackpressure) ||
        (mask & layer_state_t::eIgnoreDestinationFrame) ||
        (mask & layer_state_t::eLayerIsDisplayDecoration) ||
        (mask & layer_state_t::eLayerIsRefreshRateIndicator)) {
        s->what |= layer_state_t::eFlagsChanged;
    }
    // 清除mask标志位,即eLayerHidden。
    s->flags &= ~mask;
    // 由于flags为0,所以这里并没有改变flag
    s->flags |= (flags & mask);
    // 更新mask
    s->mask |= mask;

    registerSurfaceControlForCallback(sc);
    return *this;
}

上面的代码实际上就是用于设置标志位的,由于我们设置的flags=0,而mask=layer_state_t::eLayerHidden,所以调用该方法会清除eLayerHidden标志位。因此达到将Surface显示(show)出来的目的。

4 setBackgroundColor函数

cpp 复制代码
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundColor(
        const sp<SurfaceControl>& sc, const half3& color, float alpha, ui::Dataspace dataspace) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }

    s->what |= layer_state_t::eBackgroundColorChanged;
    s->bgColor.rgb = color; // rbg颜色
    s->bgColor.a = alpha; // 透明度
    s->bgColorDataspace = dataspace; // 颜色空间

    registerSurfaceControlForCallback(sc);
    return *this;
}

setBackgroundColor 方法,主要用于设置一个 SurfaceControl 对象的背景色。它通过操作 layer_state_t 结构体的成员,修改背景颜色相关的状态。

5 setAlpha函数

cpp 复制代码
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha(
        const sp<SurfaceControl>& sc, float alpha) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    if (alpha < 0.0f || alpha > 1.0f) {
        ALOGE("SurfaceComposerClient::Transaction::setAlpha: invalid alpha %f, clamping", alpha);
    }
    s->what |= layer_state_t::eAlphaChanged;
    s->color.a = std::clamp(alpha, 0.f, 1.f);

    registerSurfaceControlForCallback(sc);
    return *this;
}

setAlpha 主要用于修改 SurfaceControl 对象的透明度,确保 alpha 值在有效范围内,并通过设置标志位 eAlphaChanged 通知系统进行透明度更新。

setBackgroundColor 方法里面可以对背景的透明度进行设置,而这里设置的是整个Surface的透明度(包括背景和内容)。这是有区别的

6 setLayerStack函数

cpp 复制代码
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayerStack(
        const sp<SurfaceControl>& sc, ui::LayerStack layerStack) {
    layer_state_t* s = getLayerState(sc);
    if (!s) {
        mStatus = BAD_INDEX;
        return *this;
    }
    s->what |= layer_state_t::eLayerStackChanged;
    s->layerStack = layerStack;

    registerSurfaceControlForCallback(sc);
    return *this;
}

这个方法就是用于设置LayerStack属性。这里简单讲述一下LayerStack的作用:

  1. Layer顺序的控制: LayerStack控制Layer在整个渲染系统中的显示顺序。较高的LayerStack值通常代表较"前"显示的Layer,而较低的LayerStack值则代表较"后"的Layer。
  2. 多显示设备支持LayerStack在多显示设备系统中尤为重要。例如,一个设备可能连接多个显示屏,每个显示屏可能有不同的LayerStack。在这种情况下,每个显示设备可能有独立的LayerStack,用来控制各自显示的Layer顺序。不同显示设备之间的Layer层级关系可以通过不同的LayerStack值来区分。

7 apply函数

这段代码是 SurfaceComposerClient::Transaction::apply 方法的实现,它是 Android 图形系统中应用事务的核心函数之一。该方法负责将所有挂起的图层操作应用到显示系统中,并最终通知 SurfaceFlinger 执行这些图层更改。此过程包括缓存图层状态、设置显示状态、同步回调等操作。

cpp 复制代码
status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) {
    if (mStatus != NO_ERROR) {
        return mStatus;
    }

    // 创建同步回调
    std::shared_ptr<SyncCallback> syncCallback = std::make_shared<SyncCallback>();
    if (synchronous) {
        syncCallback->init();
        addTransactionCommittedCallback(SyncCallback::getCallback(syncCallback),
                                        /*callbackContext=*/nullptr);
    }

    // 准备监听器回调
    bool hasListenerCallbacks = !mListenerCallbacks.empty();
    std::vector<ListenerCallbacks> listenerCallbacks;
    // For every listener with registered callbacks
    for (const auto& [listener, callbackInfo] : mListenerCallbacks) {
        auto& [callbackIds, surfaceControls] = callbackInfo;
        if (callbackIds.empty()) {
            continue;
        }

        if (surfaceControls.empty()) {
            listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds));
        } else {
            // If the listener has any SurfaceControls set on this Transaction update the surface
            // state
            for (const auto& surfaceControl : surfaceControls) {
                layer_state_t* s = getLayerState(surfaceControl);
                if (!s) {
                    ALOGE("failed to get layer state");
                    continue;
                }
                std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end());
                s->what |= layer_state_t::eHasListenerCallbacksChanged;
                s->listeners.emplace_back(IInterface::asBinder(listener), callbacks);
            }
        }
    }

    // 调用 `cacheBuffers` 来缓存所有需要更新的图层缓冲区。
    cacheBuffers();

    // 准备 ComposerState 和 DisplayState
    Vector<ComposerState> composerStates;
    Vector<DisplayState> displayStates;
    uint32_t flags = 0;

    for (auto const& kv : mComposerStates) {
        composerStates.add(kv.second);
    }

    displayStates = std::move(mDisplayStates);

    // 设置事务标志
    if (mAnimation) {
        flags |= ISurfaceComposer::eAnimation;
    }
    if (oneWay) {
        if (synchronous) {
            ALOGE("Transaction attempted to set synchronous and one way at the same time"
                  " this is an invalid request. Synchronous will win for safety");
        } else {
            flags |= ISurfaceComposer::eOneWay;
        }
    }

    // 处理早期唤醒标志
    if (mEarlyWakeupStart && !mEarlyWakeupEnd) {
        flags |= ISurfaceComposer::eEarlyWakeupStart;
    }
    if (mEarlyWakeupEnd && !mEarlyWakeupStart) {
        flags |= ISurfaceComposer::eEarlyWakeupEnd;
    }

    // 获取 applyToken
    sp<IBinder> applyToken = mApplyToken ? mApplyToken : sApplyToken;

    // 提交事务到 SurfaceFlinger
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
                            mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
                            mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId,
                            mMergedTransactionIds);
    
    // 生成新事务ID并清理当前状态
    mId = generateId();
    clear();

    // 如果是同步事务则等待
    if (synchronous) {
        syncCallback->wait();
    }

    mStatus = NO_ERROR;
    return NO_ERROR;
}
相关推荐
安卓理事人6 小时前
安卓LinkedBlockingQueue消息队列
android
万能的小裴同学7 小时前
Android M3U8视频播放器
android·音视频
q***57748 小时前
MySql的慢查询(慢日志)
android·mysql·adb
JavaNoober8 小时前
Android 前台服务 "Bad Notification" 崩溃机制分析文档
android
城东米粉儿9 小时前
关于ObjectAnimator
android
zhangphil10 小时前
Android渲染线程Render Thread的RenderNode与DisplayList,引用Bitmap及Open GL纹理上传GPU
android
火柴就是我11 小时前
从头写一个自己的app
android·前端·flutter
lichong95112 小时前
XLog debug 开启打印日志,release 关闭打印日志
android·java·前端
用户693717500138412 小时前
14.Kotlin 类:类的形态(一):抽象类 (Abstract Class)
android·后端·kotlin
火柴就是我12 小时前
NekoBoxForAndroid 编译libcore.aar
android