一、Surface::dequeueBuffer申请图形缓冲区(buffer类型为buffer_handle_t handle)
详情参考1:
android graphic(8)—surface申请GraphicBuffer过程_lyf's blog-CSDN博客
详情参考2:
Android SurfaceFlinger 学习之路(七)----创建图形缓冲区GraphicBuffer_STN_LCD的专栏-CSDN博客
总结:
1.surface先调用dequeueBuffer向BufferQueueProducer申请内存,这时会调用GraphicBufferAlloc去分配图形缓冲区,而GraphicBufferAlloc是在surfaceFlinger进程中new出来的,因此缓冲区会存在surfaceFlinger进程中,这时候就需要序列化和反序列化,将该缓冲区内存map到BufferQueue进程中;因此调用完dequeueBuffer之后,只拿到了buffer在mSlots中的下标。
2.BufferQueueProducer和surface中有大小相同的mSlots(大小为64),两者一一对应;
3. 由于BufferQueue和Surface不在同一进程,需要用requestBuffer进行内存映射,requestBuffer的核心就是:Surface传一个数组下标,然后去将BufferQueue中对应的数组下标中的GraphicBuffer对象映射到Surface中,然后保存在对应的数组中,这两个数组一一对应。
二、Surface::queueBuffer将填充好的buffer入队
Surface::dequeueBuffer申请缓冲区,在camera result buffer时,会向缓冲区里面填充数据,这时会调用Surface::queueBuffer,也就是入队,等待消费者来拿取该buffer。
Surface::queueBuffer中的重要实现:
{ // 获取buffer在mSlots中的下标,然后进BufferQueueProducer中,去拿实际的
int i = getSlotFromBufferLocked(buffer);
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
}
BufferQueueProducer::queueBuffer:
{
// 通过上面传递过来的idx,就可以找到绑定的GraphicBuffer
const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
// 通过
sp<IConsumerListener> frameAvailableListener;
frameAvailableListener = mCore->mConsumerListener;
if (frameAvailableListener != NULL) {
frameAvailableListener->onFrameAvailable(item);
}
}
我们先回过头去看看ImageReader_Init函数:
{
sp<IGraphicBufferProducer> gbProducer;
sp<IGraphicBufferConsumer> gbConsumer;
BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
sp<BufferItemConsumer> bufferConsumer;
bufferConsumer = new BufferItemConsumer(gbConsumer, consumerUsage, maxImages,
/*controlledByApp*/true);
}
看一下BufferItemConsumer的构造函数:
BufferItemConsumer::BufferItemConsumer(
const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
int bufferCount, bool controlledByApp) :
ConsumerBase(consumer, controlledByApp){
status_t err = mConsumer->setConsumerUsageBits(consumerUsage);
LOG_ALWAYS_FATAL_IF(err != OK,
"Failed to set consumer usage bits to %#" PRIx64, consumerUsage);
if (bufferCount != DEFAULT_MAX_BUFFERS) {
err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
LOG_ALWAYS_FATAL_IF(err != OK,
"Failed to set max acquired buffer count to %d", bufferCount);
}
}
再看看ConsumerBase的构造:
ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
mAbandoned(false),
mConsumer(bufferQueue),
mPrevFinalReleaseFence(Fence::NO_FENCE) {
// Choose a name using the PID and a process-unique ID.
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
// ConsumerBase是继承于ConsumerListener的,因此这里的this就是ConsumerBase本身
wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
}
其中mConsumer->consumerConnect最终执行BufferQueueConsumer::connect,这个函数里面有一个重要的赋值:mCore->mConsumerListener = consumerListener;
也就是ConsumerBase把自己作为监听,传递给了mCore->mConsumerListener。
现在再看看BufferQueueProducer中执行的frameAvailableListener->onFrameAvailable(item),这里就很清楚了,也就是执行ConsumerBase::onFrameAvailable
void ConsumerBase::onFrameAvailable(const BufferItem& item) {
CB_LOGV("onFrameAvailable");
sp<FrameAvailableListener> listener;
{ // scope for the lock
Mutex::Autolock lock(mFrameAvailableMutex);
listener = mFrameAvailableListener.promote();
}
if (listener != NULL) {
CB_LOGV("actually calling onFrameAvailable");
listener->onFrameAvailable(item);
}
}
问题又来了,ConsumerBase::mFrameAvailableListener又是在何时赋值的?
继续看ImageReader_init函数:
{
sp<BufferItemConsumer> bufferConsumer;
bufferConsumer->setFrameAvailableListener(ctx);
}
BufferConsumer中没有实现setFrameAvailableListener方法,那直接看其父类中该方法ConsumerBase::setFrameAvailableListener的实现:
void ConsumerBase::setFrameAvailableListener(
const wp<FrameAvailableListener>& listener) {
CB_LOGV("setFrameAvailableListener");
Mutex::Autolock lock(mFrameAvailableMutex);
mFrameAvailableListener = listener;
}
综上,BufferQueueProducer::queueBuffer会将绘制完毕的buffer进行入队操作(mSlots中相应位置),再将该slot状态变成QUEUE,然后告诉监听类(ImageReader_init中new出来的JNIImageReaderContext)该buffer已经准备好了,可以取出来消费了。我们发现BufferQueueProducer和surface之间并没有实际的buffer传递,而是在传递GraphicBuffer handle,这是共享内存的一个优点,可以大大降低传输延迟。我们只要知道GraphicBuffer在BufferQueueProducer::mSlots的下标,就能找到绑定的GraphicBuffer。
三、GraphicBuffer就是常说的图形缓存区,在surfaceFlinger进程中申请的,因为GraphicBuffer对象在new时,会用GraphicBufferAllocate
GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
PixelFormat inFormat, uint32_t inLayerCount, uint64_t usage, std::string requestorName)
: GraphicBuffer() {
mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount,
usage, std::move(requestorName));
}
status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight,
PixelFormat inFormat, uint32_t inLayerCount, uint64_t inUsage,
std::string requestorName)
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
uint32_t outStride = 0;
status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount,
inUsage, &handle, &outStride, mId,
std::move(requestorName));
if (err == NO_ERROR) {
mBufferMapper.getTransportSize(handle, &mTransportNumFds, &mTransportNumInts);
width = static_cast<int>(inWidth);
height = static_cast<int>(inHeight);
format = inFormat;
layerCount = inLayerCount;
usage = inUsage;
usage_deprecated = int(usage);
stride = static_cast<int>(outStride);
}
return err;
}
这里会通过get方法先获取到GraphicBufferAllocator(单例)对象,然后用其allocate方法来申请一段内存。GraphicBufferAllocator是在SurfaceFlinger中new出来的。
先看下GraphicBufferAllocator构造函数:
GraphicBufferAllocator::GraphicBufferAllocator() : mMapper(GraphicBufferMapper::getInstance()) {
mAllocator = std::make_unique<const Gralloc3Allocator>(
reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper()));
if (mAllocator->isLoaded()) {
return;
}
mAllocator = std::make_unique<const Gralloc2Allocator>(
reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()));
if (mAllocator->isLoaded()) {
return;
}
LOG_ALWAYS_FATAL("gralloc-allocator is missing");
}
这里面又创建了另一个核心类GraphicBufferMapper,用作映射内存,这也是个单例类,然后根据版本创建GrallocAllocator对象,只要一个对象创建成功就返回,看下GrallocAllocator的构造:
Gralloc3Allocator::Gralloc3Allocator(const Gralloc3Mapper& mapper) : mMapper(mapper) {
mAllocator = IAllocator::getService();
if (mAllocator == nullptr) {
ALOGW("allocator 3.x is not supported");
return;
}
}
IAllocator这就是HIDL接口3.0版本
using android::hardware::graphics::allocator::V3_0::IAllocator;
好了,调用完GraphicBufferAllocator的构造后,mAllocator和mMapper对象都有了。回过头去看GraphicBufferAllocator::allocate方法的实现:
status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height, PixelFormat format,
uint32_t layerCount, uint64_t usage,
buffer_handle_t* handle, uint32_t* stride,
std::string requestorName) {
return allocateHelper(width, height, format, layerCount, usage, handle, stride, requestorName,
true);
}
status_t GraphicBufferAllocator::allocateHelper(uint32_t width, uint32_t height, PixelFormat format,
uint32_t layerCount, uint64_t usage,
buffer_handle_t* handle, uint32_t* stride,
std::string requestorName, bool importBuffer) {
status_t error = mAllocator->allocate(requestorName, width, height, format, layerCount, usage,
1, stride, handle, importBuffer);
……
}
接下来就是用Gralloc3Allocator去分配图形缓冲区了。这里就不再往下进行分析了,至少我们知道:
Gralloc3Allocator用于分配内存;
GraphicBufferMapper用于映射内存;
详情参考:https://blog.csdn.net/qq_34211365/article/details/106782063