? 申请buffer?
ANativeWindow_Buffer outBuffer;
surface->lock(&outBuffer, NULL);
? 首先使用dequeueBuffer申请buffer然后把这个buffer包装成backBuffer
? 最后调用backBuffer->lockAsync得到一个vaddr(虚拟地址)?
? 然后把这个vaddr(虚拟地址)赋值给outBuffer->bits,这个就是最终把数据填充的地址
? 路径??frameworks/native/libs/gui/Surface.cpp
status_t Surface::lock(
ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
{
if (mLockedBuffer != 0) {
ALOGE("Surface::lock failed, already locked");
return INVALID_OPERATION;
}
if (!mConnectedToCpu) {
//获得显示器分辨率等信息
int err = Surface::connect(NATIVE_WINDOW_API_CPU);
if (err) {
return err;
}
// we're intending to do software rendering from this point
setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
}
ANativeWindowBuffer* out;
int fenceFd = -1;
//从队列中取出buffer
status_t err = dequeueBuffer(&out, &fenceFd);
if (err == NO_ERROR) {
sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
const Rect bounds(backBuffer->width, backBuffer->height);
...
void* vaddr;
status_t res = backBuffer->lockAsync(
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
newDirtyRegion.bounds(), &vaddr, fenceFd);
ALOGW_IF(res, "failed locking buffer (handle = %p)",backBuffer->handle);
if (res != 0) {
err = INVALID_OPERATION;
} else {
mLockedBuffer = backBuffer;
outBuffer->width = backBuffer->width;
outBuffer->height = backBuffer->height;
outBuffer->stride = backBuffer->stride;
outBuffer->format = backBuffer->format;
outBuffer->bits = vaddr;
}
...
}
? ?Surface的dequeueBuffer 会跨进程调用
? ?远程的mGraphicBufferProducer消费者的dequeueBuffer
? ?mGraphicBufferProducer->dequeueBuffer
? ? ? ?向surfaceflinger发出申请,surfaceflinger申请内存。得到buf为int类型是数组mSlots下标。
? ? ? ?向surfaceflinger请求返回文件句柄fd,然后返回在app端mmap
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
ATRACE_CALL();
ALOGV("Surface::dequeueBuffer");
...
int buf = -1;
sp<Fence> fence;
nsecs_t startTime = systemTime();
FrameEventHistoryDelta frameTimestamps;
status_t result = mGraphicBufferProducer->dequeueBuffer(
&buf, &fence, reqWidth, reqHeight,
reqFormat,reqUsage,&mBufferAge,
enableFrameTimestamps ?
&frameTimestamps : nullptr);
if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) {
if (mReportRemovedBuffers && (gbuf != nullptr)) {
mRemovedBuffers.push_back(gbuf);
}
result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
if (result != NO_ERROR) {
ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
mGraphicBufferProducer->cancelBuffer(buf, fence);
return result;
}
}
}
????????mGraphicBufferProducer->dequeueBuffer
? ? ? ?向surfaceflinger发出申请,surfaceflinger申请内存。得到buf为int类型是数组mSlots下标。
?由此可以看出IGraphicBufferProducer.cpp派生出两个binder通信接口
? ??BnGraphicBufferProducer??、?BpGraphicBufferProducer(也就是Surface使用的)
? ? 而BnGraphicBufferProducer则派生出了BufferQueueProducer
????????waitForFreeSlotThenRelock等待空闲的Slot得到后锁定
? ? ? ??分配buffer
路径??frameworks/native/libs/gui/BufferQueueProducer.cpp
status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* outFence,uint32_t width, uint32_t height, PixelFormat format,uint64_t usage, uint64_t* outBufferAge,FrameEventHistoryDelta* outTimestamps) {
...
//找到空闲的Slot并锁定
while (found == BufferItem::INVALID_BUFFER_SLOT) {
status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue,
&found);
if (status != NO_ERROR) {
return status;
}
...
//判断是否需要分配 需要则分配
if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
width, height, format, BQ_LAYER_COUNT, usage,
{mConsumerName.string(), mConsumerName.size()});
allocator.allocate调用GrallocHAL模块来分配内存
GraphicBufferAllocator::get();构造函数打开HAL模块
? 路径? frameworks/native/libs/ui/GraphicBuffer.cpp?
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)
{
//打开HAL模块
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) {
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;
}
|