Android P 显示流程分析--- buffer的生产消费者模式

上篇分析到了FramebufferSurface调用acquireBufferLocked()时,从mConsumer->acquireBuffer 消费者模式中获取的,这篇我们来分析下消费者模式。

  • StreamSpliter
  • ComsumerListener
  • BufferQueue
  • BufferQueueProducter
  • BufferQueueComsumer
  • BufferQueueCore
  • BufferLayer

每个BufferLayer在onFirstRef()也就是初始化时, 都会调用createBufferQueue,初始化一个BufferQueueProducer 和 一个BufferQueueConsumer,然后将这个BufferQueueProducer和surfaceFlinger 指针 封装到MonitoredProducer中。 将 BufferQueueConsumer 和 SurfaceFinger中的RenderEngine 一起封装到BufferLayerConsumer, 然后这个BufferLayerConsumer 设置监听setContentsChangedListener(this)。 同时在BufferLayer中实现了onFrameAvailable(*), 文件当contentChange时, 调用onFrameAvailable。
onFrameAvailable的被调用流程

那我们来看看谁调用了onFrameAvailable()。grep一番之后,发现BufferQueueProducer的queueBuffer里,有调用onFrameAvailable。继续跟进,发现Surface的queueBuffer中有调用mGraphicBufferProducer->queueBuffer(slot, queueInput, queueOutput), 继续往下追,发现Surface的unlockAndPost()会调用,它会被dispatchUnlockAndPost调用。 还发现另外一个地方就是ANativeWindow中 ANativeWindow_dequeueBuffer里有调用。这个就与Android里的window挂上构了。同时发现Surface里的attachAndQueueBuffer会queeuBuffer了。这个再向上追溯可以查到android.view.surface的通过jni调用attachAndQueueBuffer 以及 SurfaceControl 调用的screenShot。而Surface的attachAndQueueBuffer 更多的是被应用快照所调用。

因为现在BufferQueueProducer和BufferQueueConsumer里都有attachBuffer, detachBuffer 和 queueBuffer , dequeueBuffer 这四个函数, 那我们先来看看BufferQueueProducer是怎么获取attachBuffer里的Buffer的
BufferQueuProducer的attachBuffer调用流程
那现在看到的attachBuffer的都不是普通的调用, 一个是Camera的视频流方式,另一种是ScreenShot的截图方式。这种不是我们想要找的,那我们去看看BufferQueueProducer的requestBuffer的流程。

status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
   
   
	......
    mSlots[slot].mRequestBufferCalled = true;
    *buf = mSlots[slot].mGraphicBuffer;
    return NO_ERROR;
}

就是把mSlots[slot]的mGraphicBuffer的地址赋值给参数buf。

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
   
   
	...
	  int buf = -1;
    sp<Fence> fence;
    nsecs_t startTime = systemTime();

    FrameEventHistoryDelta frameTimestamps;
    //graphicBufferProducer 调用 dequeueBuffer,获取buf 和 fence
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
                                                            reqFormat, reqUsage, &mBufferAge,
                                                            enableFrameTimestamps ? &frameTimestamps
                                                                                  : nullptr);
    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
      if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
   
   
        if (mReportRemovedBuffers && (gbuf != nullptr)) {
   
   
            mRemovedBuffers.push_back(gbuf);
        }//获取buf和gbuf
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
        if (result != NO_ERROR) {
   
   
            ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
            mGraphicBufferProducer->cancelBuffer(buf, fence);
            return result;
        }
    }

    if (fence->isValid()) {
   
   
        *fenceFd = fence->dup();
        if (*fenceFd == -1) {
   
   
            ALOGE("dequeueBuffer: error duping fence: %d", errno);
            // dup() should never fail; something is badly wrong. Soldier on
            // and hope for the best; the worst that should happen is some
            // visible corruption that lasts until the next frame.
        }
    } else {
   
   
        *fenceFd = -1;
    }
	//gbuf 赋值给buffer
    *buffer = gbuf.get();
    

surface的dequeueBuffer中 会先调用mGraphicBufferProducer的dequeueBuffer , 然后再调用mGraphicBufferProducer里的requestBuffer,

Surface里的lock()函数会调用dequeueBuffer函数:
Surface里的dispatchlock() 又会调用lock(), perform() 通过NATIVE_WINDOW_LOCK 也会调用dispatchLock()。最后android_view_TextureView.cpp 中 android_view_textureView_lockCanvas() 通过native_window_lock() 又会调用到NATIVE_WINDOW_LOCK。很明显 android_view_textureView_lockCanvas() 就是TextureView 调用lockCanvas()调用到的。这样就明白了TextureView是如何画出来的了。

那我们来总结下GraphicBufferProducer的使用
GraphicBufferProducer的使用
那我们看看GraphicBufferConsumer是如何对应处理的
我们还是接之前的BufferLayer来分析,当应用快照时,会调用到BufferLayer的onFrameAvailable()

void BufferLayer::onFrameAvailable(const BufferItem& item) {
   
   
	...
		//BufferItem 加入到mQueueItem的队列中
        mQueueItems.push_back(item);
        android_atomic_inc(&mQueuedFrames);
        // Wake up any pending callbacks
        mLastFrameNumberReceived = item.mFrameNumber;
        mQueueItemCondition.broadcast();
		//surfaceFlinger 通知图层更新
        mFlinger->signalLayerUpdate();
}
void SurfaceFlinger::signalLayerUpdate
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值