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

安庆网站建设推广关键词指数

安庆网站建设推广,关键词指数,简单的静态网站,腾讯邮箱企业邮箱登录我们在工作的过程中#xff0c;肯定听过分析卡顿或者冻屏问题的时候#xff0c;定位到APP卡在dequeueBuffer方法里面#xff0c;或者也听身边的同事老说3Buffer等信息。所以3Buffer是什么鬼#xff1f;什么是BufferQueue?搞Android#xff0c;你一定知道Graphic Buffer和…我们在工作的过程中肯定听过分析卡顿或者冻屏问题的时候定位到APP卡在dequeueBuffer方法里面或者也听身边的同事老说3Buffer等信息。所以3Buffer是什么鬼什么是BufferQueue?搞Android你一定知道Graphic Buffer和 Buffer Queue, 你的笔记中肯定也有下面这张Graphic Buffer的状态迁移图。系统中有两类Buffer Queue如下图所示Layer背后的Buffer Queue第一类也是最为大家所熟知的就是Layer背后的BufferQueue用来连接App与SurfaceFlinger。App为Producer端而 SurfaceFlinger 为 Consumer 端。App 绘制时先从 Buffer Queue 中 dequeue调用 Producer 的 dequeueBuffer()函数出来一块图形缓冲绘制完成后再把绘制好的图形缓冲 queue调用 Producer 的 queueBuffer()函数到 Buffer Queue 中并通知 SurfaceFlinger来消费。SurfaceFlinger 收到通知后从 Buffer Queue 中 acquire 一块绘制过的 Buffer然后进行合成处理要么进行 GPU合成要么交给 HWC 去合成。合成完成之后这个块 Buffer 就恢复自由身会被返回到 Buffer Queue 中调用 Consumer 的 releaseBuffer()函数以备下一次使用。但是在Android S代码上面谷歌对SurfaceFlinger的代码进行了重构从个人理解是为了减少SF的负责Android S开始强制App端创建BufferQueue也就是强制Client端分配Buffer。在Android S的代码中引入了一个BLASTBufferQueue.java(后面简称BBQ)这个类ViewRootImpl.java在调用relayoutWindow函数的时候会创建BBQ这个对象。Surface getOrCreateBLASTSurface() {if (!mSurfaceControl.isValid()) {return null;}Surface ret null;if (mBlastBufferQueue null) {mBlastBufferQueue new BLASTBufferQueue(mTag, mSurfaceControl,mSurfaceSize.x, mSurfaceSize.y,mWindowAttributes.format);// We only return the Surface the first time, as otherwise// it hasnt changed and there is no need to update.ret mBlastBufferQueue.createSurface();} else {mBlastBufferQueue.update(mSurfaceControl,mSurfaceSize.x, mSurfaceSize.y,mWindowAttributes.format);}return ret; } 在BBQ对象初初始化的时候会调用nativeCreate方法BBQ对象会在构造方法中传入SurfaceControl对象而这样就会和SurfaceFlinger创建了一个连接通道。SurfaceControl.java封装了很多Client调用的binder接口而服务端是SurfaceFlinger。通过nativeCreate本地方法通过JNIandroid_graphics_BLASTBufferQueue.cpp的nativeCreate方法创建了native层的BBQ。static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring jName, jlong surfaceControl,jlong width, jlong height, jint format) {String8 str8;if (jName) {const jchar* str16 env-GetStringCritical(jName, nullptr);if (str16) {str8 String8(reinterpret_castconst char16_t*(str16), env-GetStringLength(jName));env-ReleaseStringCritical(jName, str16);str16 nullptr;}}std::string name str8.string();spBLASTBufferQueue queue new BLASTBufferQueue(name, reinterpret_castSurfaceControl*(surfaceControl), width,height, format);queue-incStrong((void*)nativeCreate);return reinterpret_castjlong(queue.get()); } BLASTBufferQueue::BLASTBufferQueue(const std::string name, const spSurfaceControl surface,int width, int height, int32_t format): mSurfaceControl(surface),mSize(width, height),mRequestedSize(mSize),mFormat(format),mNextTransaction(nullptr) {createBufferQueue(mProducer, mConsumer);// since the adapter is in the client process, set dequeue timeout// explicitly so that dequeueBuffer will blockmProducer-setDequeueTimeout(std::numeric_limitsint64_t::max());// safe default, most producers are expected to override thismProducer-setMaxDequeuedBufferCount(2);mBufferItemConsumer new BLASTBufferItemConsumer(mConsumer,GraphicBuffer::USAGE_HW_COMPOSER |GraphicBuffer::USAGE_HW_TEXTURE,1, false);static int32_t id 0;mName name # std::to_string(id);auto consumerName mName (BLAST Consumer) std::to_string(id);mQueuedBufferTrace QueuedBuffer - mName BLAST# std::to_string(id);id;mBufferItemConsumer-setName(String8(consumerName.c_str()));mBufferItemConsumer-setFrameAvailableListener(this);mBufferItemConsumer-setBufferFreedListener(this);mBufferItemConsumer-setDefaultBufferSize(mSize.width, mSize.height);mBufferItemConsumer-setDefaultBufferFormat(convertBufferFormat(format));mBufferItemConsumer-setBlastBufferQueue(this);ComposerService::getComposerService()-getMaxAcquiredBufferCount(mMaxAcquiredBuffers);mBufferItemConsumer-setMaxAcquiredBufferCount(mMaxAcquiredBuffers);mTransformHint mSurfaceControl-getTransformHint();mBufferItemConsumer-setTransformHint(mTransformHint);SurfaceComposerClient::Transaction().setFlags(surface, layer_state_t::eEnableBackpressure,layer_state_t::eEnableBackpressure).setApplyToken(mApplyToken).apply();mNumAcquired 0;mNumFrameAvailable 0;BQA_LOGV(BLASTBufferQueue created width%d height%d format%d mTransformHint%d, width,height, format, mTransformHint); } 从上面的代码中createBufferQueue创建了BufferQueue同时也创建了Graphic Buffer的生产者和消费者。其中有个代码mProducer - setMaxDequeuedBufferCount(2)这个就和3Buffer有关系了我们先整理下Buffer的运转过程如图所示App的RenderThread 调用 Producer.dequeueBuffer()在BufferQueue中拿到一个空闲的Buffer。App的RenderThread调用Producer.queueBuffer将绘制好的 Buffer 入列。注意此时入列的 Buffer 可能还未绘制完成即 GPU 可能还在进行绘制工作。最终调用到 Procuder 的 Bn 端即 SurfaceFliner 进程里的某个 Binder 线程里。在 Bn 端会通过调用SurfaceFlinger的SetTransactionState方法把当前的带有Buffer信息的State保存到一个TransactionQueue队列中。当带有Buffer信息的Layer信息保存到队列中 这个动作称作“上帧”。所以我么可以在 systrace 上看到该Layer待消费的 Buffer 数目1。而 Buffer Queue 的消费者就是 SurfaceFlinger所以在下一个 Vsync信号到来后在 SurfaceFlinger 的 handleMessageInvalidate()函数中调用 acquireBuffer()去取 Buffer取走之后BufferQueue 中待消费的 Buffer 便减少一个。因为有上帧所以要重新进行合成SurfaceFlinger 调用onMessageRefresh()函数去做合成一般是 HWC 合成直接把 Buffer 交给 HWC。合成完成后在 postComposition()里会调用binder接口进行通讯。App端的binder收到消息后调用releaseBuffer()释放 Buffer如 systrace 所示这里释放的是上一帧的 Buffer。上面图中7个步骤就是一个buffer详细的转运过程。DisplayDevice 背后的Buffer Queue第二类Buffer Queue是GPU合成特有的一般在游戏APP渲染过程中会遇到这个Buffer Queue隐藏在DisplayDevice之后是在SurfaceFlinger为每个接入系统的显示屏创建DisplayDevice实例时创建的。执行在SurfaceFlinger::processDisplayAdded函数中。void SurfaceFlinger::processDisplayAdded(const wpIBinder displayToken,const DisplayDeviceState state) {......spcompositionengine::DisplaySurface displaySurface;spIGraphicBufferProducer producer;spIGraphicBufferProducer bqProducer;spIGraphicBufferConsumer bqConsumer;getFactory().createBufferQueue(bqProducer, bqConsumer, /*consumerIsSurfaceFlinger */false);...... }这个函数是为DisplaySurface创建BufferQueue createBufferQueue函数是指向BufferQueue::createBufferQueue传入的第三个参数 consumerIsSurfaceFlinger 为false表示BufferQueue的消费者不是SurfaceFlinger。void SurfaceFlinger::processDisplayAdded(const wpIBinder displayToken,const DisplayDeviceState state) {......if (state.isVirtual()) {const auto displayId VirtualDisplayId::tryCast(compositionDisplay-getId());LOG_FATAL_IF(!displayId);auto surface spVirtualDisplaySurface::make(getHwComposer(), *displayId, state.surface,bqProducer, bqConsumer, state.displayName);displaySurface surface;producer std::move(surface);} else {ALOGE_IF(state.surface ! nullptr,adding a supported display, but rendering surface is provided (%p), ignoring it,state.surface.get());const auto displayId PhysicalDisplayId::tryCast(compositionDisplay-getId());LOG_FATAL_IF(!displayId);displaySurface spFramebufferSurface::make(getHwComposer(), *displayId, bqConsumer,state.physical-activeMode-getSize(),ui::Size(maxGraphicsWidth, maxGraphicsHeight));producer bqProducer;}...... }除了虚拟盘主屏或者外屏采用FrameBufferSurface继承自ConsumerBase把BufferQueueConsumer封装到FrameBufferSurface里面。Buffer共享Buffer分配Buffer同步fence后面三个点的内容还在整理中等整理完毕再同步到这章内容中。
http://www.dnsts.com.cn/news/139116.html

相关文章:

  • 做网站要多少像素网站图片居中代码
  • 网站模板怎么建设厦门模板建站哪家好
  • 中国银行官网登录入口成都优化网站建设
  • 金华网站建设哪个公司好点小红书官方推广
  • 学校建设外文网站情况成都小程序开发价格
  • 大气企业网站源码公司网站制作方案
  • 企业网站 asp.netapp定制开发运营推广方案
  • 引用网站的内容如何做注释百度竞价排名叫什么
  • 大背景类型的网站设计技术支持 英铭网站建设
  • 源代码管理网站物流网站建设可行性分析
  • 网上购物有哪些网站?台州做微网站
  • 网站优化协议龙华龙岗网站建设公司
  • 做淘宝客没网站怎么打造自己的网站
  • 官网建设流程织梦网站内部优化
  • 如何做企业网站界面营销网站怎么做
  • 平面设计提高审美网站WordPress首页站内搜索
  • 外贸网站定制建站动画设计是做什么的
  • 网站建设十年杜绝模板做网站需要多少钱 百度
  • 秦皇岛网站建设青岛开发区网站建设哪家好
  • 永久持续更新网站优化关键词
  • 长春建站培训ftp网站目录
  • 微网站建设及开发wordpress登陆过程
  • 帮人做非法网站吗网站统计源码下载
  • 企业响应式网站建设app开发多少钱一个
  • 鹤壁高端网站建设百度关键词排名优化
  • wordpress的网站wordpress 删除版权信息
  • 仙桃做网站找谁上海营销seo
  • 哪个网站设计好jsp网站开发难吗
  • 阜阳建设大厦网站不同网站的主机和域名
  • 合肥市住房建设局网站phpmyadmin 备份 wordpress