上篇分析到了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()。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的
那现在看到的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的使用
那我们看看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