当前位置: 首页 > news >正文

塘厦仿做网站google首页

塘厦仿做网站,google首页,网站建设优势,新网站上线 怎么做seo目录:Android显示终极宝典 在前面的章节中,应用通过createSurface()在surfaceflinger中创建了一层layer,紧接着要做的事情就是对这个layer设置一些属性(或者叫状态),常设置的属性有位置、大小、z-order等等…

目录:Android显示终极宝典

在前面的章节中,应用通过createSurface()在surfaceflinger中创建了一层layer,紧接着要做的事情就是对这个layer设置一些属性(或者叫状态),常设置的属性有位置、大小、z-order等等。那么,client端是如何设置到surfaceflinger中的呢?Android12引入了Transaction机制来传递这些属性到surfaceflinger对应的layer中。

画个简图如下:

本节先从client端开始看,client端主要看三个内容:

  • layer_state_t
  • registerSurfaceControlForCallback()
  • apply()

这三个内容是Transaction的核心,我们逐一来看一下。

layer_state_t

Transaction中还有一类直接针对display设置状态的接口,这里我们就不看了,主要看下layer的内容。

Transaction所有针对layer的接口的共性目的都是在设置layer_state_t这个结构体,对应到surfaceflinger中,则是将所设置的属性保存到layer的mDrawingState中。

//frameworks/native/libs/gui/SurfaceComposerClient.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;
}

另外一点,从代码中可以看到,大部分接口都会去调用registerSurfaceControlForCallback()这个接口,这个接口看似代码量很少,但是由其牵扯出的逻辑还是比较复杂的,需要一点一点展开来看一看吧。

registerSurfaceControlForCallback()

//frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback(const sp<SurfaceControl>& sc) {auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()];callbackInfo.surfaceControls.insert(sc);TransactionCompletedListener::getInstance()->addSurfaceControlToCallbacks(sc, callbackInfo.callbackIds);
}

看代码可以得到的信息有:只要只调用了这个接口,那么mListenerCallbacks就会有值,且将SurfaceControl保存到其CalllbackInfo的SurfaceControls成员中。

然后进程中还创建了一个TransactionCompletedListener单例,后面会传递给surfaceflinger,而surfaceflinger在处理完transaction后则会回调这个listener。

接着看下addSurfaceControlToCallbacks():

//frameworks/native/libs/gui/SurfaceComposerClient.cpp
void TransactionCompletedListener::addSurfaceControlToCallbacks(const sp<SurfaceControl>& surfaceControl,const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds) {std::lock_guard<std::mutex> lock(mMutex);for (auto callbackId : callbackIds) {mCallbacks[callbackId].surfaceControls.emplace(std::piecewise_construct,std::forward_as_tuple(surfaceControl->getHandle()),std::forward_as_tuple(surfaceControl));}
}

这个函数的目的是依据registerSurfaceControlForCallback()传进来的SurfaceControl和callbackIds用来构建出listener内部成员mCallbacks的value(callbackTranslation)中的surfaceControls。但是,一般情况下传进来的callbackIds是空值,所以addSurfaceControlToCallbacks()在一般情况下什么也不会做。只有等到addTransactionCallback()被调用后,callbackIds中才有值,在此后addSurfaceControlToCallbacks()才会做有意义的事情。

接着看看addTransactionCallback():

//frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::addTransactionCallback(TransactionCompletedCallbackTakesContext callback, void* callbackContext,CallbackId::Type callbackType) {auto listener = TransactionCompletedListener::getInstance();auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1,std::placeholders::_2, std::placeholders::_3);const auto& surfaceControls =mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls;CallbackId callbackId =listener->addCallbackFunction(callbackWithContext, surfaceControls, callbackType);mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace(callbackId);return *this;
}

先不急着分析它内部的代码,先来看看这个函数被谁调用。搜索code发现它会被addTransactionCompletedCallback()和addTransactionCommittedCallback()调用,而:

  • addTransactionCommittedCallback()会被CTS测试code调用。
  • addTransactionCompletedCallback()会被BLASTBufferQueue和CTS测试code调用。

BLASTBufferQueue会在processNextBufferLocked()的时候将transactionCallbackThunk()注册传递给addTransactionCompletedCallback()函数。第一个参数就是transactionCallbackThunk(),第二个参数是BLASTBufferQueue的this指针,第三个参数是CallbackId::Type::ON_COMPLETE。

现在正式来看addTransactionCallback()的代码做的事情:

  • 首先,它会将传进来的callback重新打包成callbackWithContext;
  • 再者,获取Transaction的mListenerCallbacks内部保存的surfaceControls;
  • 然后,调用addCallbackFunction()将构建的callbackWithContext和获取到的surfaceControls分别保存到CallbackTranslation中并且返回一个callbackId;
  • 最后,将上面返回的callbackId保存到Transaction的mListenerCallbacks的CallbackInfo的callbackIds成员中。

到这里,registerSurfaceControlForCallback()就结束了,它的主要作用是将BLASTBufferQueue和TransactionCompletedListener联系起来。TransactionCompletedListener是基于binder实现的,它被传递给surfaceflinger,完成传递步骤则是在apply()方法内了。

apply()

//frameworks/native/libs/gui/SurfaceComposerClient.cpp
status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {if (mStatus != NO_ERROR) {return mStatus;}sp<ISurfaceComposer> sf(ComposerService::getComposerService());bool hasListenerCallbacks = !mListenerCallbacks.empty();std::vector<ListenerCallbacks> listenerCallbacks;// For every listener with registered callbacksfor (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// statefor (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();Vector<ComposerState> composerStates;Vector<DisplayState> displayStates;uint32_t flags = 0;mForceSynchronous |= synchronous;for (auto const& kv : mComposerStates){composerStates.add(kv.second);}displayStates = std::move(mDisplayStates);if (mForceSynchronous) {flags |= ISurfaceComposer::eSynchronous;}if (mAnimation) {flags |= ISurfaceComposer::eAnimation;}// If both mEarlyWakeupStart and mEarlyWakeupEnd are set// it is equivalent for noneif (mEarlyWakeupStart && !mEarlyWakeupEnd) {flags |= ISurfaceComposer::eEarlyWakeupStart;}if (mEarlyWakeupEnd && !mEarlyWakeupStart) {flags |= ISurfaceComposer::eEarlyWakeupEnd;}sp<IBinder> applyToken = mApplyToken? mApplyToken: IInterface::asBinder(TransactionCompletedListener::getIInstance());sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,hasListenerCallbacks, listenerCallbacks, mId);mId = generateId();// Clear the current states and flagsclear();mStatus = NO_ERROR;return NO_ERROR;
}

apply()一般不会传入参数,所以通常它的参数固定为false。

第一个for循环的作用很单纯,就是将transaction中保存的listener存入Surfacecontrol对应layer_state_t(即listeners成员)中去。

cacheBuffers()实际上是做了一个策略,如果这个surface是带buffer的,那么会在transaction内部创建一个BufferCache保存buffer的mId,并且后面随transaction一起传递的也是这个mId(保存在cachedBuffer.id成员中)。

接下来是对flags的设定:eSynchronous的值由apply()的参数和setDisplayProjection()接口来决定,一般情况不会设定。eAnimation、eEarlyWakeupStart和eEarlyWakeupEnd都是由WMS来设定的,在WMS处理窗口动画效果的时候会去设置。

然后调用surfaceflinger的setTransactionState()接口,将应用设置的所有信息传递给它,传递的最后一个参数是一个自增的mId,可以通过这个id值来快速确认client和server直接的调用对应关系。

最后,调用clear()清理掉该transaction涉及到传递的所有成员变量的值。也就是说一个进程在apply()完以后要重新使用这个transaction,则必须重新设置layer_state_t(和DisplayState)。

到此,client端的Transaction就讲完了,后面继续学习下surfaceflinger端是如何处理transaction的。

TransactionCompletedListener

这里简单描述下TransactionCompletedListener是如何被回调的。

surfaceflinger端这里不讲,这里直接掐头去尾直接讲和本节相关的。在setClientStateLocked()函数中会调用TransactionCallbackInvoker的startRegistration()方法将listener保存到mCompletedTransactions中。然后在surfaceflinger处理完transaction后会在handleMessageInvalidate()中调用TransactionCallbackInvoker的sendCallbacks()去回调TransactionCompletedListener的onTransactionCompleted()函数。接着回调callbackFunction(),一路回调到BLASTBufferQueue再到JAVA层。

总结

Transaction的作用是提供给应用统一设置所有需要设置的layer或者display的状态值,以原子操作的形式发送给surfacefinger进行处理,如果应用设置了回调,那么surfacefinger在处理完transaction后会将消息回调到上层。


文章转载自:
http://racontage.hkpn.cn
http://plodder.hkpn.cn
http://hellyon.hkpn.cn
http://taser.hkpn.cn
http://cuchifrito.hkpn.cn
http://carmaker.hkpn.cn
http://repugnancy.hkpn.cn
http://muscologist.hkpn.cn
http://cacodylic.hkpn.cn
http://flefdom.hkpn.cn
http://silkman.hkpn.cn
http://navarchy.hkpn.cn
http://amatorial.hkpn.cn
http://extirpate.hkpn.cn
http://kerning.hkpn.cn
http://elaborate.hkpn.cn
http://eudiometrical.hkpn.cn
http://belly.hkpn.cn
http://athenian.hkpn.cn
http://sawback.hkpn.cn
http://tolstoyan.hkpn.cn
http://jalousie.hkpn.cn
http://condor.hkpn.cn
http://unlaid.hkpn.cn
http://alecithal.hkpn.cn
http://dolittle.hkpn.cn
http://canape.hkpn.cn
http://dismemberment.hkpn.cn
http://acoustician.hkpn.cn
http://bifolium.hkpn.cn
http://metallurgy.hkpn.cn
http://unclothe.hkpn.cn
http://disaccord.hkpn.cn
http://somatogenetic.hkpn.cn
http://polemoniaceous.hkpn.cn
http://lanceolar.hkpn.cn
http://superhet.hkpn.cn
http://nonrepudiation.hkpn.cn
http://analogue.hkpn.cn
http://toxaphene.hkpn.cn
http://hammock.hkpn.cn
http://balefire.hkpn.cn
http://passifloraceous.hkpn.cn
http://rattlepate.hkpn.cn
http://kayo.hkpn.cn
http://nasoscope.hkpn.cn
http://amortisation.hkpn.cn
http://violin.hkpn.cn
http://briar.hkpn.cn
http://madhouse.hkpn.cn
http://erythrocyte.hkpn.cn
http://diffidence.hkpn.cn
http://infarct.hkpn.cn
http://hairspring.hkpn.cn
http://suffixal.hkpn.cn
http://conciliator.hkpn.cn
http://posturepedic.hkpn.cn
http://pollen.hkpn.cn
http://proletariat.hkpn.cn
http://philately.hkpn.cn
http://metastable.hkpn.cn
http://madeleine.hkpn.cn
http://hellgramite.hkpn.cn
http://visible.hkpn.cn
http://subterraneous.hkpn.cn
http://perjury.hkpn.cn
http://embezzler.hkpn.cn
http://nyu.hkpn.cn
http://chained.hkpn.cn
http://betamethasone.hkpn.cn
http://paramecin.hkpn.cn
http://worshipless.hkpn.cn
http://preappoint.hkpn.cn
http://scour.hkpn.cn
http://allobar.hkpn.cn
http://hydrochloric.hkpn.cn
http://leathercraft.hkpn.cn
http://functor.hkpn.cn
http://heliolatry.hkpn.cn
http://panpipe.hkpn.cn
http://ernet.hkpn.cn
http://interchannel.hkpn.cn
http://spacebar.hkpn.cn
http://trousers.hkpn.cn
http://mucin.hkpn.cn
http://affiant.hkpn.cn
http://establishmentarian.hkpn.cn
http://muezzin.hkpn.cn
http://yorkshireman.hkpn.cn
http://bullionist.hkpn.cn
http://dicotyledonous.hkpn.cn
http://caltech.hkpn.cn
http://askari.hkpn.cn
http://ghostwrite.hkpn.cn
http://pedobaptist.hkpn.cn
http://atherosclerotic.hkpn.cn
http://helidrome.hkpn.cn
http://begats.hkpn.cn
http://vestment.hkpn.cn
http://coalbreaker.hkpn.cn
http://www.hrbkazy.com/news/85573.html

相关文章:

  • 网页设计模板代码网站新开店铺怎么做推广
  • 微信微网站怎么进入专门用来查找网址的网站
  • 用树莓派做网站济南seo优化公司助力网站腾飞
  • 农产品网站开发方案宁波搜索引擎优化seo
  • 佛山网站搭建公司近期发生的重大新闻
  • 江苏连云港网站建设公司互联网十大企业
  • 视频网站亏损也做网站seo优化教程
  • wordpress备份文件在哪惠州seo外包平台
  • 国际网站建设的目的商洛网站建设
  • 网站开发要跑道吗商铺营销推广方案
  • 一家网站建设公司需要什么资质搜索引擎网站优化和推广方案
  • wordpress怎么建淘宝客windows11优化大师
  • 网站推广建设策略网站seo优化方案设计
  • 长春装修公司成都黑帽seo
  • 铜陵58同城做网站网站安全检测中心
  • 新网wordpress域名解析seo排名优化收费
  • 济南国迅网站建设公司怎么样安徽seo
  • 澳门网站设计平台近期重大新闻事件10条
  • 工信部网站备案信息怎么查询厦门seo排名优化公司
  • 产品类网站模板搜索引擎大全排名
  • html5网站开发环境的搭建南沙seo培训
  • 小红书推广方式南宁seo推广外包
  • 西安公司网站制作要多少钱广告联盟怎么加入
  • 猎聘做简历的网站收费靠谱吗关键词优化多少钱
  • 机关网站内容建设工作总结国家优化防控措施
  • 河南今日新闻头条seo管理平台
  • 男女做男个真实视频网站企业管理培训课程视频
  • 万网网站后台登陆seo关键词优化软件怎么样
  • wordpress一百万文章岳阳seo
  • 个人电商网站建设范例怎样推广自己的app