显示系统[4] APP申请创建Buffer分配Buffer的过程

  申请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;
        }
    ...
}

   SurfacedequeueBuffer 会跨进程调用

   远程的mGraphicBufferProducer消费者的dequeueBuffer

   mGraphicBufferProducer->dequeueBuffer

       surfaceflinger发出申请,surfaceflinger申请内存。得到bufint类型是数组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申请内存。得到bufint类型是数组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;
}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值