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;
}
相关推荐
yangfeipancc3 小时前
数据库-用户管理
android·数据库
字节流动3 小时前
Android Java 版本的 MSAA OpenGL ES 多重采样
android·java·opengles
xuanfengwuxiang3 小时前
安卓帧率获取
android·python·测试工具·adb·性能优化·pycharm
柯南二号7 小时前
Task ‘wrapper‘ not found in project ‘:example‘. 报错解决
android·gradle·hippy
我又来搬代码了7 小时前
【Android】项目升级时报错 android:style/Holo.Widget
android·gitee
洞见不一样的自己10 小时前
android 常用方法
android
暗碳10 小时前
华为麦芒5(安卓6)termux记录 使用ddns-go,alist
android·linux
seven272911 小时前
Android MQTT关于断开连接disconnect报错原因
android·mqtt·disconnect报错
Maplee14 小时前
Compose 转场动画之 Transition
android·前端
weixin_4825655315 小时前
Android IC读写器安卓小程序 3
android·小程序