首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

SurfaceFlinger03-Transaction基础

  • 25-04-23 10:20
  • 2371
  • 10207
juejin.cn

前言

Transaction表示一个事务,是整个图形子系统非常重要的一个组件,从native层到framework层,它贯穿于surfaceflinger、system_server以及gui库中,所有surfaceflinger用于合成、显示的图形数据都是通过Transaction从业务进程提交到surfaceflinger中。

业务进程中,通过给Transaction设置各种数据,就可以将这些数据以事务的方式同步提交给surfaceflinger中,surfaceflinger中就能够在一帧内将这些数据应用到不同的图层对象上。

本篇文章主要从以下及方面对Transaction进行分析说明:

  1. Transaction的作用;
  2. Transaction的实现和数据结构;
  3. Transaction的主要操作;
  4. Transaction的提交过程。

一、Transaction的作用

Transaction的作用可以总结为一句话:

以"事务"的方式,将不同业务进程、不同图层或屏幕相关数据和属性同步提交给surfaceflinger进程,进行合成与显示。

  • 支持多个图层设置: 一个Transaction上可以设置多个图层或屏幕属性;

  • 支持跨进程传递:Transaction可以在不同进程间进行传递,并且支持合并操作,因此可以将不同进程设置的图层属性通过同一个Transaction传递给surfaceflinger进程,实现不同进程在同一帧的合成显示。

二、Transaction的实现

在代码架构中分别在Native层和Java层同时实现了Transaction类:

  • 一部分是位于native层gui库中的Transaction类定义,作为SurfaceComposerClient类中的内部类实现;
  • 另一部分是位于框架层的Transaction类定义,作为SurfaceControl类的静态内部类实现;

transaction.jpg

natvie层的Transaction是作为核心,框架层的Transaction则是暴露给框架层用于Java程序创建native Transaction对象的接口:

  • 当框架侧创建Java类型Transaction实例时,会同步创建与之对应且唯一的native层Transaction实例;
  • 当框架侧Transaction传递图层/屏幕数据时,会根据同名方法,通过JNI层将数据传递给native Transaction,并进一步发送给surfaceflinger进程。

下面具体看下其初始化过程和数据封装对象。

2.1、Transaction初始化

Java层Transaction提供了三个构造方法:

java
代码解读
复制代码
// frameworks/base/core/java/android/view/SurfaceControl.java public Transaction() { this(nativeCreateTransaction()); } private Transaction(long nativeObject) { // native Transaction对象转换后的long类型值 mNativeObject = nativeObject; // 用于内存回收 mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject); } private Transaction(Parcel in) { readFromParcel(in); }

无论哪个方法,都会得到一个native层Transaction对象进行关联。在默认构造方法中,通过nativeCreateTransaction()方法向native发起调用,并完成了native 层Transaction对象的创建:

cpp
代码解读
复制代码
// frameworks/base/core/jni/android_view_SurfaceControl.cpp static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) { return reinterpret_cast(new SurfaceComposerClient::Transaction); } // frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction::Transaction() { mId = generateId(); }

以上构造方法中,创建了一个mId,每个Transaction会有且只有唯一的Id。

在native层中,还实现了拷贝构造,用于创建对象副本:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction::Transaction(const Transaction& other) : mId(other.mId), mTransactionNestCount(other.mTransactionNestCount), // 该Transaction中是否在执行动画 mAnimation(other.mAnimation), mEarlyWakeupStart(other.mEarlyWakeupStart), mEarlyWakeupEnd(other.mEarlyWakeupEnd), // 该Transaction中是否有SurfaceControl包含Buffer,用于缓存Buffer时进行判断 mMayContainBuffer(other.mMayContainBuffer), mDesiredPresentTime(other.mDesiredPresentTime), mIsAutoTimestamp(other.mIsAutoTimestamp), // Vsync id、时间戳等帧信息 mFrameTimelineInfo(other.mFrameTimelineInfo), // 进行apply时的token标记,用于sf中对Transaction入队操作 mApplyToken(other.mApplyToken) { // 所有屏幕数据列表 mDisplayStates = other.mDisplayStates; // 所有图层数据列表 mComposerStates = other.mComposerStates; // 触控事件焦点窗口更新列表 mInputWindowCommands = other.mInputWindowCommands; // 所有回调事件列表 mListenerCallbacks = other.mListenerCallbacks; }

拷贝构造函数在 C++ 中主要用于:

  • 初始化新对象时复制现有对象;
  • 执行赋值操作时复制对象;
  • 将对象作为函数参数或返回值时复制;
  • 容器和算法需要复制对象时。

拷贝构造中初始化的这些属性,是Transaction类中的主要成员变量。其中有4个结构体成员:

  • SortedVector mDisplayStates:DisplayState列表,DisplayState用于在Transaction对象中保存跟屏幕相关的参数,一个屏幕对应一个DisplayState对象,用token进行标记;

  • std::unordered_map, ComposerState, IBinderHash> mComposerStates:ComposerState映射表,ComposerState用于在Transaction对象中保存图层(Layer)相关的参数,一个Layer对应一个ComposerState对象,以sp形式的LayerHandler为键保存在mComposerStates中;

  • std::unordered_map, CallbackInfo, TCLHash> mListenerCallbacks:代表一个Transaction对象中的所有事件监听的映射表,CallbackInfo封装了一个具体的事件监听信息。

  • InputWindowCommands mInputWindowCommands:用于处理窗口与输入事件相关操作,如焦点窗口更新。

下面对DisplayState和ComposerState进行说明,剩余两个成员变量在之后的流程中进行重点说明。

2.2、DisplayState

DisplayState对象用于保存跟屏幕相关的参数。system_server进程更新屏幕显示区域、方向后,会先将更新内容保存在DisplayState中,并在Transaction apply后,将这些数据传递给surfaceflinger进程,从而完成屏幕相关属性的更新。

DisplayState定义如下:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/include/gui/LayerState.h struct DisplayState { enum { eSurfaceChanged = 0x01, // 表示虚拟屏所显示的Surface发生变化的标记 eLayerStackChanged = 0x02, // 表示屏幕LayerStack发生变化的标记 eDisplayProjectionChanged = 0x04, // 表示屏幕实际显示区域发生变化的标记 eDisplaySizeChanged = 0x08, // 表示虚拟屏屏幕大小发生变化的标记 eFlagsChanged = 0x10 // 表示其他特殊flag发生变化的标记 }; DisplayState(); void merge(const DisplayState& other); void sanitize(int32_t permissions); uint32_t what = 0; // 标记值 uint32_t flags = 0; sp token; // Display的token标记 sp surface; // 虚拟屏用于显示内容的Surface ui::LayerStack layerStack = ui::DEFAULT_LAYER_STACK;// 屏幕的LayerStack ui::Rotation orientation = ui::ROTATION_0; // 屏幕方向 Rect layerStackSpaceRect = Rect::EMPTY_RECT; // 逻辑屏大小 Rect orientedDisplaySpaceRect = Rect::EMPTY_RECT; // 实际内容显示区域 uint32_t width = 0; // 逻辑屏宽高 uint32_t height = 0; status_t write(Parcel& output) const; // 用于序列化操作 status_t read(const Parcel& input); };

在使用过程中,会根据token值来决定是否更新或创建新的DisplayState对象,比如要更新屏幕的大小时:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp void SurfaceComposerClient::Transaction::setDisplaySize(const sp& token, uint32_t width, uint32_t height) { // 获取token对应的DisplayState DisplayState& s(getDisplayState(token)); s.width = width; s.height = height; s.what |= DisplayState::eDisplaySizeChanged; }

getDisplayState(token)方法中根据token从mDisplayStates获取所对应元素索引:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp& token) { DisplayState s; s.token = token; // 根据token判断列表中是否存在DisplayState ssize_t index = mDisplayStates.indexOf(s); if (index < 0) { // 不存在时,将s放入列表中 s.what = 0; index = mDisplayStates.add(s); } return mDisplayStates.editItemAt(static_cast<size_t>(index)); }

之所以仅能通过token就能获得索引,是因为重写了compare_type()方法:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp static inline int compare_type(const DisplayState& lhs, const DisplayState& rhs) { return compare_type(lhs.token, rhs.token); }

SortedVector就是通过compare_type对两个元素进行比较。

2.3、ComposerState

ComposerState对象用于保存跟图层相关的参数。图形缓冲数据(GraphicBuffer)、窗口大小、位置、层级等都是先保存在对应的ComposerState中,并在Transaction apply后,将这些数据传递给surfaceflinger进程并更新。

ComposerState中只有一个layer_state_t属性,它其实就是layer_state_t的一层“壳”:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/include/gui/LayerState.h class ComposerState { public: layer_state_t state; status_t write(Parcel& output) const; status_t read(const Parcel& input); };

真正保存图层数据的是layer_state_t结构体。layer_state_t中定义了所有用于更新图层数据的属性:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/include/gui/LayerState.h struct layer_state_t { ...... sp surface; // sp类型LayerHandler int32_t layerId; // layer id uint64_t what; // flag float x; // Layer左上角x轴坐标,用于指定Layer位置 float y; // Layer左上角y轴坐标 int32_t z; // Layer的层级值 ui::LayerStack layerStack = ui::DEFAULT_LAYER_STACK; // layerstack值,用于跟屏幕进行匹配 uint32_t flags; // 标记位 uint32_t mask; //标记位 uint8_t reserved; matrix22_t matrix; // Layer的变换矩阵,用于指定Layer位置 float cornerRadius; // Layer圆角半径 uint32_t backgroundBlurRadius; // 背景模糊半径 ...... // non POD must be last. see write/read Region transparentRegion; // 透明区域 uint32_t bufferTransform; // Buffer变换矩阵 bool transformToDisplayInverse; Rect crop; // 裁剪区域 std::shared_ptr bufferData = nullptr; // bufferData中封装了Buffer相关数据 ui::Dataspace dataspace; HdrMetadata hdrMetadata; ...... };

ComposerState以sp形式的LayerHandle为key,保存在mComposerStates列表中,创建或获取ComposerState对象时,通过getLayerState()方法获取:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp& sc) { // 获取LayerHandle对象 auto handle = sc->getLayerStateHandle(); if (mComposerStates.count(handle) == 0) { // 不存在对应的ComposerState时,将s添加到映射表中 ComposerState s; s.state.surface = handle; s.state.layerId = sc->getLayerId(); mComposerStates[handle] = s; } // 返回ComposerState对象的layer_state_t return &(mComposerStates[handle].state); }

三、Transaction的主要操作

这里对常见的Transaction更新操作进行总结。

3.1、屏幕信息更新

  1. Transaction::setDisplayLayerStack():设置对应屏幕的LayerStack值
cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp void SurfaceComposerClient::Transaction::setDisplayLayerStack(const sp& token, ui::LayerStack layerStack) { DisplayState& s(getDisplayState(token)); // 更新layerStack s.layerStack = layerStack; // 设置layerStack更新标记 s.what |= DisplayState::eLayerStackChanged; }

LayerStack是用于管理在一个屏幕上所显示Layer的一个ID值,简单说就是一个逻辑屏上显示的所有Layer集合。当Layer的LayerStack值和DisplayDevice的LayerStack值相同时,说明这个Layer可以在这个Display上显示。

一般情况下,屏幕的LayerStack值为逻辑屏ID,灭屏后将设置为-1。

  1. Transaction::setDisplayProjection():设置对应屏幕的方向和显示区域
cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp void SurfaceComposerClient::Transaction::setDisplayProjection(const sp& token, ui::Rotation orientation, const Rect& layerStackRect, const Rect& displayRect) { DisplayState& s(getDisplayState(token)); s.orientation = orientation; // 设置方向 s.layerStackSpaceRect = layerStackRect; // 设置逻辑屏大小 s.orientedDisplaySpaceRect = displayRect; // 设置显示区域大小 s.what |= DisplayState::eDisplayProjectionChanged; // 更新标记 }

layerStackSpaceRect表示逻辑屏大小,orientedDisplaySpaceRect表示实际显示区域大小。所有图层最终显示的区域是通过以上参数经过旋转、平移、缩放等操作决定。

  1. Transaction::setDisplaySize():设置虚拟屏屏幕大小

该方法用于设置虚拟屏的屏幕大小,物理屏大小在加载时便确认。

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp void SurfaceComposerClient::Transaction::setDisplaySize(const sp& token, uint32_t width, uint32_t height) { DisplayState& s(getDisplayState(token)); s.width = width; s.height = height; s.what |= DisplayState::eDisplaySizeChanged; }

3.2、图层可见性

  1. Transaction.show():显示指定的图层
cpp
代码解读
复制代码
// frameworks/base/core/java/android/view/SurfaceControl.java public Transaction show(SurfaceControl sc) { ..... // 从flags上清除SURFACE_HIDDEN标记 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN); return this; }
  1. Transaction.hide():隐藏指定的图层
cpp
代码解读
复制代码
// frameworks/base/core/java/android/view/SurfaceControl.java public Transaction hide(SurfaceControl sc) { // 从flags上设置SURFACE_HIDDEN标记 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN); return this; }
  1. Transaction.setOpaque():设置图层是否为不透明
cpp
代码解读
复制代码
// frameworks/base/core/java/android/view/SurfaceControl.java public Transaction setOpaque(@NonNull SurfaceControl sc, boolean isOpaque) { checkPreconditions(sc); if (isOpaque) { // 从flags上设置SURFACE_OPAQUE标记,表示不透明 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE); } else { // 从flags上清除SURFACE_OPAQUE标记,表示透明 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_OPAQUE); } return this; }

以上三个方法都是通过设置flag进行区分,最终是将所有flag更新给了layer_state_t对象的flags变量:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags( const sp& sc, uint32_t flags, uint32_t mask) { layer_state_t* s = getLayerState(sc); ...... s->what |= layer_state_t::eFlagsChanged; // 表示标记有更新 s->flags &= ~mask; // 清除mask s->flags |= (flags & mask); // 将mask值更新给flag s->mask |= mask; registerSurfaceControlForCallback(sc); return *this; }
  1. Transaction.setAlpha():设置图层的透明度
cpp
代码解读
复制代码
// frameworks/base/core/java/android/view/SurfaceControl.java public Transaction setAlpha(@NonNull SurfaceControl sc, @FloatRange(from = 0.0, to = 1.0) float alpha) { ....... nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha); return this; } // frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha( const sp& sc, float alpha) { layer_state_t* s = getLayerState(sc); s->what |= layer_state_t::eAlphaChanged; s->color.a = std::clamp(alpha, 0.f, 1.f); // 将alpha更新给s->color.a变量 registerSurfaceControlForCallback(sc); return *this; }

3.3、图层位置及大小更新

  1. Transaction::setPosition():设置图层的顶点坐标
cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( const sp& sc, float x, float y) { layer_state_t* s = getLayerState(sc); s->what |= layer_state_t::ePositionChanged; s->x = x; // 设置x轴顶点坐标 s->y = y; // 设置y轴顶点坐标 ...... return *this; }
  1. Transaction::setCrop():设置图层显示区域大小
cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCrop( const sp& sc, const Rect& crop) { layer_state_t* s = getLayerState(sc); s->what |= layer_state_t::eCropChanged; s->crop = crop; // 设置图层的显示区域大小 ..... return *this; }
  1. Transaction::setMatrix():设置图层变换矩阵
cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setMatrix( const sp& sc, float dsdx, float dtdx, float dtdy, float dsdy) { layer_state_t* s = getLayerState(sc); s->what |= layer_state_t::eMatrixChanged; layer_state_t::matrix22_t matrix; matrix.dsdx = dsdx; // X轴缩放系数 matrix.dtdx = dtdx; // X轴变化时,y轴的切变因子 matrix.dsdy = dsdy; // Y轴缩放系数 matrix.dtdy = dtdy; // Y轴轴变化时,x轴的切变因子 s->matrix = matrix; registerSurfaceControlForCallback(sc); return *this; }

关于图层几何位置如何计算,见《SurfaceFlinger10-Transform介绍 》

3.4、图层层级更新

  1. Transaction::setLayer():设置图层的Z轴层级值
cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer( const sp& sc, int32_t z) { layer_state_t* s = getLayerState(sc); s->what |= layer_state_t::eLayerChanged; s->what &= ~layer_state_t::eRelativeLayerChanged; // 设置层级值 s->z = z; ...... return *this; }
  1. Transaction::setRelativeLayer():设置图层的相对层级值
cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setRelativeLayer( const sp& sc, const sp& relativeTo, int32_t z) { layer_state_t* s = getLayerState(sc); s->what |= layer_state_t::eRelativeLayerChanged; s->what &= ~layer_state_t::eLayerChanged; // 设置相对图层 s->relativeLayerSurfaceControl = relativeTo; // 设置层级值 s->z = z; ...... return *this; }

关于图层层级相关详细分析,见《SurfaceFlinger09-Layer层级结构管理 》。

3.5、Transaction::setBuffer():设置图层显示内容Buffer

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer( const sp& sc, const sp& buffer, const std::optional>& fence, const std::optional<uint64_t>& optFrameNumber, uint32_t producerId, ReleaseBufferCallback callback) { layer_state_t* s = getLayerState(sc); releaseBufferIfOverwriting(*s); // 创建BufferData std::shared_ptr bufferData = std::make_shared(); bufferData->buffer = buffer; // 设置Buffer属性 if (buffer) { uint64_t frameNumber = sc->resolveFrameNumber(optFrameNumber); bufferData->frameNumber = frameNumber; bufferData->producerId = producerId; bufferData->flags |= BufferData::BufferDataChange::frameNumberChanged; if (fence) { bufferData->acquireFence = *fence; bufferData->flags |= BufferData::BufferDataChange::fenceChanged; } // 标记releaseBufferCallback是否在当前线程 bufferData->releaseBufferEndpoint = IInterface::asBinder(TransactionCompletedListener::getIInstance()); setReleaseBufferCallback(bufferData.get(), callback); } if (mIsAutoTimestamp) { mDesiredPresentTime = systemTime(); } s->what |= layer_state_t::eBufferChanged; s->bufferData = std::move(bufferData); registerSurfaceControlForCallback(sc); // 注册TransactionCompletedCallback监听 addTransactionCompletedCallback([](void*, nsecs_t, const sp&, const std::vector&) {}, nullptr); mMayContainBuffer = true; return *this; }

四、Transaction的提交

当Transaction数据填充完毕后,通过apply()方法就可以将该Transaction提交给surfaceflinger。

根据apply()方法参数的不同,可以分为异步提交和同步提交:

  • 异步提交:发起IPC调用后,不阻塞当前线程;
  • 同步提交:发起IPC调用后,会通过信号量阻塞当前线程,surfaceflinger中完成提交后通知信号量解除阻塞;
  • one_way:表示客户端跟surfaceflinger的IPC调用为"单向"调用,执行后直接返回,不等待返回结果,不阻塞调用线程;
  • 非one_way:表示客户端需要等待此次跨进程调用的返回结果,返回结果后才会继续执行。

如果设置了oneWay标记,就不能设置为同步提交。

默认为非同步、非oneWay方式执行apply()方法。

apply()方法如下:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) { // 1. SyncCallback中定义了一个信号量,在同步提交时用于阻塞当前调用线程 std::shared_ptr syncCallback = std::make_shared(); if (synchronous) { // 如果是同步提交模式,则初始化一个信号量,并注册一个Transaction Commit监听 syncCallback->init(); addTransactionCommittedCallback(SyncCallback::getCallback(syncCallback), /*callbackContext=*/nullptr); } // 2. 处理所有事件监听 bool hasListenerCallbacks = !mListenerCallbacks.empty(); std::vector listenerCallbacks; // 将所有各类事件监听以ListenerCallbacks方式放置在列表中,并传递给sf for (const auto& [listener, callbackInfo] : mListenerCallbacks) { auto& [callbackIds, surfaceControls] = callbackInfo; if (callbackIds.empty()) { continue; } // 对不针对某一具体SurfaceControl的事件监听,放在listenerCallbacks列表中传递给sf进行处理 if (surfaceControls.empty()) { listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds)); } else { // 对具体SurfaceControl的事件监听,放置在其内部的ListenerCallbacks列表中传递给sf for (const auto& surfaceControl : surfaceControls) { layer_state_t* s = getLayerState(surfaceControl); std::vector callbacks(callbackIds.begin(), callbackIds.end()); s->what |= layer_state_t::eHasListenerCallbacksChanged; s->listeners.emplace_back(IInterface::asBinder(listener), callbacks); } } } // 3. 处理GraphicBuffer缓存 cacheBuffers(); // 4. 填充ComposerState列表和DisplayState列表 Vector composerStates; Vector displayStates; uint32_t flags = 0; for (auto const& kv : mComposerStates) { composerStates.add(kv.second); } displayStates = std::move(mDisplayStates); if (mAnimation) { flags |= ISurfaceComposer::eAnimation; } // oneWay和synchronous不能同时为true 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; } } // 5. 设置eEarlyWakeupStart和eEarlyWakeupEnd标记 if (mEarlyWakeupStart && !mEarlyWakeupEnd) { flags |= ISurfaceComposer::eEarlyWakeupStart; } if (mEarlyWakeupEnd && !mEarlyWakeupStart) { flags |= ISurfaceComposer::eEarlyWakeupEnd; } // 6. 设置applyToken并向sf发起调用 sp applyToken = mApplyToken ? mApplyToken : sApplyToken; sp sf(ComposerService::getComposerService()); sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken, mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp, mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId, mMergedTransactionIds); mId = generateId(); // 清除该Transaction中的所有状态 clear(); // 同步操作时,开始阻塞当前调用线程,sf中完成commit后通过事件回调方法解除 if (synchronous) { syncCallback->wait(); } mStatus = NO_ERROR; return NO_ERROR; }

以上方法中:

  1. 处理同步提交操作:

如果设置了同步提交,则通过SyncCallback初始化一个信号量,并注册一个TransactionCommit回调,在发起调用后进入wait状态,当sf中完成commit操作后,通过TransactionCommit回调通知SyncCallback解除阻塞;

  1. 处理事件监听:

将所有类型事件监听以ListenerCallbacks方式放置在列表中,并传递给sf;

  1. 处理GraphicBuffer缓存:

通过缓存的方式优化GraphicBuffer在业务进程和sf进程的传递,业务进程将GraphicBuffer缓存在了BufferCache中,当第一次使用一个buffer时,会进行缓存,并传递到sf进程中同步进行缓存;之后的调用中,将仅传递buffer id,并通过buffer id在缓存中获得对应的buffer;

  1. 设置eEarlyWakeupStart和eEarlyWakeupEnd标记:

这两标记用于调控surfaceflinger的VSYNC调度,以便提前处理图层的合成;

  1. 设置applyToken并向sf发起调用

通过setTransactionState()将向sf发起调用,sf中收到调用后,会将该Transaction放在队列中,并在下次调度时,在主线程中读取Transaction并提交Transaction上携带的参数。

入队时,以applyToken为键,相同applyToken的Transaction位于同一个列表中,通过applyToken,也可以实现对同一列表中Transaction的批操作。

以上便是Transaction的一些基础知识,其中涉及的一些知识点,在后续会单独文档中进行说明。

注:本文转载自juejin.cn的Android采码蜂的文章"https://juejin.cn/post/7456785019789885481"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top