AndroidQ 图形系统(7)GraphicBuffer内存分配与Gralloc

在前面dequeueBuffer函数说了,申请buffer时会首先从mFreeBuffers中取已经绑定了GraphicBuffer且状态为FREE的BufferSlot,如果没有则会从mFreeSlots中取还未绑定GraphicBufferBufferSlot,并且会设置BUFFER_NEEDS_REALLOCATION这个flag,之后就会给GraphicBuffer分配内存空间:

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()});
        	......        
        }

并且我们发现不管是dequeueBuffer还是queueBuffer传递的都是BufferSlot的index,并没有传递真正GraphicBuffer,那如何做到同一个GraphicBuffer两个进程共享?这就用到了内存映射。

GraphicBuffer中有两个核心类用来处理内存分配(GraphicBufferAllocator)和内存映射(GraphicBufferMapper)。

GraphicBuffer父类中有个很重要的变量:

typedef struct ANativeWindowBuffer
{
	......
	const native_handle_t* handle;
   ......
} ANativeWindowBuffer_t;

这个native_handle_t最终就是GraphicBuffer句柄,handle的地址会随着allocate函数的调用向HAL层传递,native_handle_t定义在/system/core/libcutils/include/cutils/native_handle.h中:

typedef struct native_handle
  {
      int version;        /* sizeof(native_handle_t) */
      int numFds;         /* number of file-descriptors at &data[0] */
      int numInts;        /* number of ints at &data[numFds] */
      int data[0];        /* numFds + numInts ints */
  } native_handle_t;

GraphicBuffer创建

dequeueBuffer中如果flag为BUFFER_NEEDS_REALLOCATION就会创建GraphicBuffer并未其分配内存,

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()}); 
               ......
      }

GraphicBuffer构造函数:

GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
                             uint32_t inLayerCount, uint64_t inUsage, std::string requestorName)
      : GraphicBuffer() {
    mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount, inUsage,
                              std::move(requestorName));
}

initWithSize

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;
}

这里面创建了核心类之一的GraphicBufferAllocator,这是处理GraphicBuffer内存分配的类,是个单例类,通过get获取其对象,接着就调用其allocate函数,等下再看
先看看GraphicBufferAllocator构造函数:

GraphicBufferAllocator::GraphicBufferAllocator() : mMapper(GraphicBufferMapper::getInstance()) {
    mAllocator = std::make_unique<const Gralloc3Allocator>(
            reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper()));
    if (!mAllocator->isLoaded()) {
        mAllocator = std::make_unique<const Gralloc2Allocator>(
                reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()));
    }

    if (!mAllocator->isLoaded()) {
        LOG_ALWAYS_FATAL("gralloc-allocator is missing");
    }
}

这里面又创建了另一个核心类GraphicBufferMapper,用作映射内存,这也是个单例类,再看看GraphicBufferMapper构造函数:

GraphicBufferMapper::GraphicBufferMapper() {
    mMapper = std::make_unique<const Gralloc3Mapper>();
    if (!mMapper->isLoaded()) {
        mMapper = std::make_unique<const Gralloc2Mapper>();
        mMapperVersion = Version::GRALLOC_2;
    } else {
        mMapperVersion = Version::GRALLOC_3;
    }

    if (!mMapper->isLoaded()) {
        LOG_ALWAYS_FATAL("gralloc-mapper is missing");
    }
}

可以看到GraphicBufferAllocatorGraphicBufferMapper构造函数做的事情差不多的,它们分别创建了自己用来调HAL层函数的对象,以GraphicBufferAllocator为例来看看:

GraphicBufferAllocator::GraphicBufferAllocator() : mMapper(GraphicBufferMapper::getInstance()) {
    mAllocator = std::make_unique<const Gralloc3Allocator>(
            reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper()));
    if (!mAllocator->isLoaded()) {
        mAllocator = std::make_unique<const Gralloc2Allocator>(
                reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()));
    }

    if (!mAllocator->isLoaded()) {
        LOG_ALWAYS_FATAL("gralloc-allocator is missing");
    }
}

首先创建Gralloc3Allocator,如果不支持3.0版本则创建Gralloc2Allocator,2.0版本:

Gralloc3Allocator::Gralloc3Allocator(const Gralloc3Mapper& mapper) : mMapper(mapper) {
    mAllocator = IAllocator::getService();
    if (mAllocator == nullptr) {
        ALOGW("allocator 3.x is not supported");
        return;
    }
}

bool Gralloc3Allocator::isLoaded() const {
    return mAllocator != nullptr;
}

IAllocator这就是HIDL接口3.0版本
using android::hardware::graphics::allocator::V3_0::IAllocator;
在这里插入图片描述
Android Q上并没有allocator3.0的默认实现,
在这里插入图片描述
同样mapper也没有3.0的默认实现,
所以GraphicBufferAllocatormAllocator对应Gralloc2Allocator
GraphicBufferMappermMapper对应Gralloc2Mapper

Gralloc2AllocatorGralloc2Mapper的实现都在Gralloc2.cpp中,它们相当于Gralloc模块在native层的HIDL客户端。

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,
        uint64_t /*graphicBufferId*/, std::string requestorName)
{
    ......
    status_t error =
            mAllocator->allocate(width, height, format, layerCount, usage, 1, stride, handle);
    	......
        return NO_MEMORY;
    }
}

继续调用Gralloc2Allocatorallocate函数,GraphicBuffer的handle也在往下传递。

Gralloc2Allocator::allocate

status_t Gralloc2Allocator::allocate(uint32_t width, uint32_t height, PixelFormat format,
                                     uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
                                     uint32_t* outStride, buffer_handle_t* outBufferHandles) const {
    IMapper::BufferDescriptorInfo descriptorInfo = {};
    descriptorInfo.width = width;
    descriptorInfo.height = height;
    descriptorInfo.layerCount = layerCount;
    descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
    descriptorInfo.usage = usage;

    BufferDescriptor descriptor;
    status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
                                              static_cast<void*>(&descriptor));
    if (error != NO_ERROR) {
        return error;
    }

    auto ret = mAllocator->allocate(descriptor, bufferCount,
                                    [&](const auto& tmpError, const auto& tmpStride,
                                        const auto& tmpBuffers) {
                                        error = static_cast<status_t>(tmpError);
                                        if (tmpError != Error::NONE) {
                                            return;
                                        }

                                        // import buffers
                                        for (uint32_t i = 0; i < bufferCount; i++) {
                                            error = mMapper.importBuffer(tmpBuffers[i],
                                                                         &outBufferHandles[i]);
                                            if (error != NO_ERROR) {
                                                for (uint32_t j = 0; j < i; j++) {
                                                    mMapper.freeBuffer(outBufferHandles[j]);
                                                    outBufferHandles[j] = nullptr;
                                                }
                                                return;
                                            }
                                        }

                                        *outStride = tmpStride;
                                    });

    // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
    hardware::IPCThreadState::self()->flushCommands();

    return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
}

这里把buffer相关信息封装到了IMapper::BufferDescriptorInfo中,这个结构体定义在IMapper.hal中,接着allocate就调到HAL层去了,IAllocator::getService即获取HIDL代理,具体实现是在HAL层的。

using android::hardware::graphics::allocator::V2_0::IAllocator;
Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) {
    mAllocator = IAllocator::getService();
    if (mAllocator == nullptr) {
        ALOGW("allocator 2.x is not supported");
        return;
    }
}

HAL层和frameworks通过HIDL(hwbinder)连接,类似APP和frameworks之间通过AIDL(binder)连接。

Gralloc相关的HIDL接口实现在hardware/interfaces/graphics/下:
在这里插入图片描述
可以看到buffer内存分配,buffer内存映射,buffer合成的HIDL服务都在这下面。

allocator HIDL

我们来看allocator的HIDL接口,
在这里插入图片描述
先看接口文件IAllocator.hal

package android.hardware.graphics.allocator@2.0;

import android.hardware.graphics.mapper@2.0;

interface IAllocator {
    
    dumpDebugInfo() generates (string debugInfo);
    ......
    allocate(BufferDescriptor descriptor, uint32_t count)
        generates (Error error,
                   uint32_t stride,
                   vec<handle> buffers);
};

对外提供了两个函数dumpDebugInfoallocate,接着来看 IAllocator.hal的实现,在如下目录
在这里插入图片描述
在这个目录下并没有发现类似Allocator.cpp或者AllocatorImpl.cppIAllocator.hal实现类,来看看passthrough.cpp:

#include <allocator-passthrough/2.0/GrallocLoader.h>
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>

using android::hardware::graphics::allocator::V2_0::IAllocator;
using android::hardware::graphics::allocator::V2_0::passthrough::GrallocLoader;

extern "C" IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
    return GrallocLoader::load();
}

发现了IAllocator的实现类是GrallocLoader::load(),接续跟,
allocatorGrallocLoader
hardware/interfaces/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0:

class GrallocLoader {
   public:
    static IAllocator* load() {
        const hw_module_t* module = loadModule();
        if (!module) {
            return nullptr;
        }
        auto hal = createHal(module);
        if (!hal) {
            return nullptr;
        }
        return createAllocator(std::move(hal));
    }

GrallocLoader的load函数中调用了三个关键函数,先来看loadModule

loadModule

  // load the gralloc module
    static const hw_module_t* loadModule() {
        const hw_module_t* module;
        int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
        if (error) {
            ALOGE("failed to get gralloc module");
            return nullptr;
        }

        return module;
    }

这个函数加载了ID为GRALLOC_HARDWARE_MODULE_IDgralloc HAL模块,首先看gralloc的HAL头文件,路径hardware/libhardware/include/hardware,这里定义了许多HAL模块的头文件,gralloc有两个:gralloc.hgralloc1.h,我们来看gralloc1.h,这是它的gralloc1_device_t结构体

typedef struct gralloc1_device {
    /* Must be the first member of this struct, since a pointer to this struct
     * will be generated by casting from a hw_device_t* */
    struct hw_device_t common;

    void (*getCapabilities)(struct gralloc1_device* device, uint32_t* outCount,
            int32_t* /*gralloc1_capability_t*/ outCapabilities);
            
    gralloc1_function_pointer_t (*getFunction)(struct gralloc1_device* device,
            int32_t /*gralloc1_function_descriptor_t*/ descriptor);
} gralloc1_device_t;

它里面最重要的就是getFunction这个函数,通过传递的gralloc1_function_descriptor_t获取对应函数指针,gralloc1_function_descriptor_t有如下这些

typedef enum {
    GRALLOC1_FUNCTION_INVALID = 0,
    GRALLOC1_FUNCTION_DUMP = 1,
    GRALLOC1_FUNCTION_CREATE_DESCRIPTOR = 2,
    GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR = 3,
    GRALLOC1_FUNCTION_SET_CONSUMER_USAGE = 4,
    GRALLOC1_FUNCTION_SET_DIMENSIONS = 5,
    GRALLOC1_FUNCTION_SET_FORMAT = 6,
    GRALLOC1_FUNCTION_SET_PRODUCER_USAGE = 7,
    GRALLOC1_FUNCTION_GET_BACKING_STORE = 8,
    GRALLOC1_FUNCTION_GET_CONSUMER_USAGE = 9,
    GRALLOC1_FUNCTION_GET_DIMENSIONS = 10,
    GRALLOC1_FUNCTION_GET_FORMAT = 11,
    GRALLOC1_FUNCTION_GET_PRODUCER_USAGE = 12,
    GRALLOC1_FUNCTION_GET_STRIDE = 13,
    GRALLOC1_FUNCTION_ALLOCATE = 14,
    GRALLOC1_FUNCTION_RETAIN = 15,
    GRALLOC1_FUNCTION_RELEASE = 16,
    GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES = 17,
    GRALLOC1_FUNCTION_LOCK = 18,
    GRALLOC1_FUNCTION_LOCK_FLEX = 19,
    GRALLOC1_FUNCTION_UNLOCK = 20,
    GRALLOC1_FUNCTION_SET_LAYER_COUNT = 21,
    GRALLOC1_FUNCTION_GET_LAYER_COUNT = 22,
    GRALLOC1_FUNCTION_VALIDATE_BUFFER_SIZE = 23,
    GRALLOC1_FUNCTION_GET_TRANSPORT_SIZE = 24,
    GRALLOC1_FUNCTION_IMPORT_BUFFER = 25,
    GRALLOC1_LAST_FUNCTION = 25,
} gralloc1_function_descriptor_t;

我们先暂时不管gralloc1对应的HAL的module是哪一个,接着看如下函数中的createHal

static IAllocator* load() {
        const hw_module_t* module = loadModule();
        if (!module) {
            return nullptr;
        }
        auto hal = createHal(module);
        if (!hal) {
            return nullptr;
        }
        return createAllocator(std::move(hal));
    }

createHal(module)

// create an AllocatorHal instance
    static std::unique_ptr<hal::AllocatorHal> createHal(const hw_module_t* module) {
        int major = getModuleMajorApiVersion(module);
        switch (major) {
            case 1: {
                auto hal = std::make_unique<Gralloc1Hal>();
                return hal->initWithModule(module) ? std::move(hal) : nullptr;
            }
            case 0: {
                auto hal = std::make_unique<Gralloc0Hal>();
                return hal->initWithModule(module) ? std::move(hal) : nullptr;
            }
            default:
                ALOGE("unknown gralloc module major version %d", major);
                return nullptr;
        }
    }

gralloc1.h对应的应该是Gralloc1Hal,真正使用的其实是Gralloc1Hal的子类Gralloc1HalImpl,
我们看Gralloc1HalImplinitWithModule函数:

Gralloc1HalImpl::initWithModule

bool initWithModule(const hw_module_t* module) {
        int result = gralloc1_open(module, &mDevice);
        if (result) {
            ALOGE("failed to open gralloc1 device: %s", strerror(-result));
            mDevice = nullptr;
            return false;
        }

        initCapabilities();
        if (!initDispatch()) {
            gralloc1_close(mDevice);
            mDevice = nullptr;
            return false;
        }

        return true;
    }

gralloc1_open会打开module下的device,现在还没确认module是哪一个,先不管,接着看看initDispatch()函数:

Gralloc1HalImpl::initDispatch

virtual bool initDispatch() {
        if (!initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump) ||
            !initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR, &mDispatch.createDescriptor) ||
            !initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR, &mDispatch.destroyDescriptor) ||
            !initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions) ||
            !initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat) ||
            !initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE, &mDispatch.setConsumerUsage) ||
            !initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE, &mDispatch.setProducerUsage) ||
            !initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride) ||
            !initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate) ||
            !initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release)) {
            return false;
        }

        if (mCapabilities.layeredBuffers) {
            if (!initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT, &mDispatch.setLayerCount)) {
                return false;
            }
        }

        return true;
    }

initDispatch里面调用了一系列带参数的initDispatch函数:

template <typename T>
    bool initDispatch(gralloc1_function_descriptor_t desc, T* outPfn) {
        auto pfn = mDevice->getFunction(mDevice, desc);
        if (pfn) {
            *outPfn = reinterpret_cast<T>(pfn);
            return true;
        } else {
            ALOGE("failed to get gralloc1 function %d", desc);
            return false;
        }
    }

可以看到最终还是调到Gralloc模块下的device的getFunction去获取对应函数指针,获取到的函数指针会放入mDispatch中,mDispatch结构体如下:

struct {
        GRALLOC1_PFN_DUMP dump;
        GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
        GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
        GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
        GRALLOC1_PFN_SET_FORMAT setFormat;
        GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount;
        GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
        GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
        GRALLOC1_PFN_GET_STRIDE getStride;
        GRALLOC1_PFN_ALLOCATE allocate;
        GRALLOC1_PFN_RELEASE release;
    } mDispatch = {};

mDispatch中的GRALLOC1_PFN_xxx全部是定义在gralloc1.h的函数指针,这样就完成了gralloc1.h的函数的赋值,现在只需要有一个实现getFunction的device就行了。

Gralloc模块的HAL各个厂商有自己的实现,我们这里看看高通平台的Gralloc HAL,目录/hardware/qcom/display/msm8996/libgralloc1/gr_device_impl.cpp

struct gralloc_module_t HAL_MODULE_INFO_SYM = {
  .common = {
    .tag = HARDWARE_MODULE_TAG,
    .module_api_version = GRALLOC_MODULE_API_VERSION_1_0,
    .hal_api_version    = HARDWARE_HAL_API_VERSION,
    .id = GRALLOC_HARDWARE_MODULE_ID,
    .name = "Graphics Memory Module",
    .author = "Code Aurora Forum",
    .methods = &gralloc_module_methods,
    .dso = 0,
    .reserved = {0},
  },
};

先看打开设备的函数:
gralloc_module_methods:

static struct hw_module_methods_t gralloc_module_methods = 
						{.open = gralloc_device_open};

gralloc_device_open:

int gralloc_device_open(const struct hw_module_t *module, const char *name, hw_device_t **device) {
  int status = -EINVAL;
  if (!strcmp(name, GRALLOC_HARDWARE_MODULE_ID)) {
    gralloc1::GrallocImpl * /*gralloc1_device_t*/ dev = gralloc1::GrallocImpl::GetInstance(module);
    *device = reinterpret_cast<hw_device_t *>(dev);
    if (dev) {
      status = 0;
    } else {
      ALOGE("Fatal error opening gralloc1 device");
    }
  }
  return status;
}

实际是一个GrallocImpl类,这是gralloc1_device_t的子类,定义在gr_device_impl.h 中:

class GrallocImpl : public gralloc1_device_t {
 public:
  static int CloseDevice(hw_device_t *device);
  static void GetCapabilities(struct gralloc1_device *device, uint32_t *out_count,
                              int32_t * /*gralloc1_capability_t*/ out_capabilities);
  static gralloc1_function_pointer_t GetFunction(
      struct gralloc1_device *device, int32_t /*gralloc1_function_descriptor_t*/ descriptor);

  static GrallocImpl* GetInstance(const struct hw_module_t *module) {
    static GrallocImpl *instance = new GrallocImpl(module);
    if (instance->IsInitialized()) {
      return instance;
    } else {
      return nullptr;
    }
  }

GrallocImpl构造函数中做了一些初始化:

GrallocImpl::GrallocImpl(const hw_module_t *module) {
  common.tag = HARDWARE_DEVICE_TAG;
  common.version = GRALLOC_MODULE_API_VERSION_1_0;
  common.module = const_cast<hw_module_t *>(module);
  common.close = CloseDevice;
  getFunction = GetFunction;
  getCapabilities = GetCapabilities;

  initalized_ = Init();
}

getFunction被赋值为了GrallocImpl::GetFunction

gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, int32_t function) {
  if (!device) {
    return NULL;
  }

  switch (function) {
    case GRALLOC1_FUNCTION_DUMP:
      return reinterpret_cast<gralloc1_function_pointer_t>(Dump);
    case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
      return reinterpret_cast<gralloc1_function_pointer_t>(CreateBufferDescriptor);
    case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
      return reinterpret_cast<gralloc1_function_pointer_t>(DestroyBufferDescriptor);
    case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetConsumerUsage);
    case GRALLOC1_FUNCTION_SET_DIMENSIONS:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetBufferDimensions);
    case GRALLOC1_FUNCTION_SET_FORMAT:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetColorFormat);
    case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetLayerCount);
    case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
      return reinterpret_cast<gralloc1_function_pointer_t>(SetProducerUsage);
    case GRALLOC1_FUNCTION_GET_BACKING_STORE:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetBackingStore);
    case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetConsumerUsage);
    case GRALLOC1_FUNCTION_GET_DIMENSIONS:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferDimensions);
    case GRALLOC1_FUNCTION_GET_FORMAT:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetColorFormat);
    case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetLayerCount);
    case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetProducerUsage);
    case GRALLOC1_FUNCTION_GET_STRIDE:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetBufferStride);
    case GRALLOC1_FUNCTION_ALLOCATE:
      return reinterpret_cast<gralloc1_function_pointer_t>(AllocateBuffers);
    case GRALLOC1_FUNCTION_RETAIN:
      return reinterpret_cast<gralloc1_function_pointer_t>(RetainBuffer);
    case GRALLOC1_FUNCTION_RELEASE:
      return reinterpret_cast<gralloc1_function_pointer_t>(ReleaseBuffer);
    case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
      return reinterpret_cast<gralloc1_function_pointer_t>(GetNumFlexPlanes);
    case GRALLOC1_FUNCTION_LOCK:
      return reinterpret_cast<gralloc1_function_pointer_t>(LockBuffer);
    case GRALLOC1_FUNCTION_LOCK_FLEX:
      return reinterpret_cast<gralloc1_function_pointer_t>(LockFlex);
    case GRALLOC1_FUNCTION_UNLOCK:
      return reinterpret_cast<gralloc1_function_pointer_t>(UnlockBuffer);
    case GRALLOC1_FUNCTION_PERFORM:
      return reinterpret_cast<gralloc1_function_pointer_t>(Gralloc1Perform);
    case GRALLOC1_FUNCTION_VALIDATE_BUFFER_SIZE:
      return reinterpret_cast<gralloc1_function_pointer_t>(validateBufferSize);
    case GRALLOC1_FUNCTION_GET_TRANSPORT_SIZE:
      return reinterpret_cast<gralloc1_function_pointer_t>(getTransportSize);
    case GRALLOC1_FUNCTION_IMPORT_BUFFER:
      return reinterpret_cast<gralloc1_function_pointer_t>(importBuffer);
    default:
      ALOGE("%s:Gralloc Error. Client Requested for unsupported function", __FUNCTION__);
      return NULL;
  }

  return NULL;
}

GetFunction函数中才真正给gralloc1.h中定义的函数赋了具体实现,实现都在GrallocImpl中,最终gralloc_device_open方法打开了设备,将GrallocImpl作为gralloc1_device_t的子类返回到了Gralloc1HalImpl中,保存在mDevice中。

再回到前面:

static IAllocator* load() {
        const hw_module_t* module = loadModule();
        if (!module) {
            return nullptr;
        }
        auto hal = createHal(module);
        if (!hal) {
            return nullptr;
        }
        return createAllocator(std::move(hal));
    }

最后再来看createAllocator函数

createAllocator

    // create an IAllocator instance
    static IAllocator* createAllocator(std::unique_ptr<hal::AllocatorHal> hal) {
        auto allocator = std::make_unique<hal::Allocator>();
        return allocator->init(std::move(hal)) ? allocator.release() : nullptr;
    }

创建了一个hal::Allocator,并调用了其init函数,将createHal的到Gralloc1Hal传了过去,
Allocator定义在Allocator.h中:

using Allocator = detail::AllocatorImpl<IAllocator, AllocatorHal>;

其实例为AllocatorImpl

template <typename Interface, typename Hal>
class AllocatorImpl : public Interface {
}

这是个模板类继承IAllocator,这就是IAllocator.hal的具体实现类,我们前面在SurfaceFlinger进程中的对于内存分配的调用首先就是到这里,它的init函数其实就是将Gralloc1Hal保存在了AllocatorImplmHal

bool init(std::unique_ptr<Hal> hal) {
          mHal = std::move(hal);
          return true;
      }

现在我们终于知道了前面Gralloc2Allocatorallocate函数具体是调到哪里去了,就是IAllocator.hal的实现server端AllocatorImpl

AllocatorImpl::allocate

Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
                            IAllocator::allocate_cb hidl_cb) override {
          uint32_t stride;
          std::vector<const native_handle_t*> buffers;
          Error error = mHal->allocateBuffers(descriptor, count, &stride, &buffers);
          if (error != Error::NONE) {
              hidl_cb(error, 0, hidl_vec<hidl_handle>());
              return Void();
          }
  
          hidl_vec<hidl_handle> hidlBuffers(buffers.cbegin(), buffers.cend());
          hidl_cb(Error::NONE, stride, hidlBuffers);
  
          // free the local handles
          mHal->freeBuffers(buffers);
  
          return Void();
  }

记得吗,Gralloc2Allocatorallocate函数传了一个callback过来,上面这个函数先调用mHal->allocateBuffers之后得到会通过callback将stride,hidlBuffers传回去。

我们刚刚已经知道了mHal就是Gralloc1Hal,继续看mHal->allocateBuffers函数,注意,这里将一个native_handle_t的vector地址传了过去,可以为多个buffer分配内存取决与上层传递的bufferCount

Gralloc1Hal::allocateBuffers

Error allocateBuffers(const BufferDescriptor& descriptor, uint32_t count, uint32_t* outStride,
                          std::vector<const native_handle_t*>* outBuffers) override {
        ......
        gralloc1_buffer_descriptor_t desc;
        Error error = createDescriptor(descriptorInfo, &desc);
        std::vector<const native_handle_t*> buffers;
        buffers.reserve(count);

        // allocate the buffers
        for (uint32_t i = 0; i < count; i++) {
            const native_handle_t* tmpBuffer;
            uint32_t tmpStride;
            error = allocateOneBuffer(desc, &tmpBuffer, &tmpStride);
            if (error != Error::NONE) {
                break;
            }

            buffers.push_back(tmpBuffer);

            if (stride == 0) {
                stride = tmpStride;
            } else if (stride != tmpStride) {
                // non-uniform strides
                error = Error::UNSUPPORTED;
                break;
            }
        }	
        .....
        *outStride = stride;
        *outBuffers = std::move(buffers);

        return Error::NONE;
    }

上面函数继续调用allocateOneBuffer函数:

allocateOneBuffer

Error allocateOneBuffer(gralloc1_buffer_descriptor_t descriptor,
                            const native_handle_t** outBuffer, uint32_t* outStride) {
        const native_handle_t* buffer = nullptr;
        int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer);
        if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) {
            return toError(error);
        }

        uint32_t stride = 0;
        error = mDispatch.getStride(mDevice, buffer, &stride);
        if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) {
            mDispatch.release(mDevice, buffer);
            return toError(error);
        }

        *outBuffer = buffer;
        *outStride = stride;

        return Error::NONE;
    }

allocateOneBuffer函数中接着调用mDispatch.allocate,前面已经分析过了mDispatch结构体一系列函数指针的赋值了,mDispatch.allocate的赋值函数如下:

initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate)

对应到GrallocImpl的这一条:


 gralloc1_function_pointer_t GrallocImpl::GetFunction(gralloc1_device_t *device, int32_t function) {
	    ...
     switch (function) {
		......
			case GRALLOC1_FUNCTION_ALLOCATE:
       return reinterpret_cast<gralloc1_function_pointer_t>(AllocateBuffers);
		......
	}

即对应的HAL实现为AllocateBuffers函数:

GrallocImpl::AllocateBuffers

gralloc1_error_t GrallocImpl::AllocateBuffers(gralloc1_device_t *device, uint32_t num_descriptors,
                                                const gralloc1_buffer_descriptor_t *descriptors,
                                                buffer_handle_t *out_buffers) {
    if (!num_descriptors || !descriptors) {
      return GRALLOC1_ERROR_BAD_DESCRIPTOR;
    }
  
    GrallocImpl const *dev = GRALLOC_IMPL(device);
    gralloc1_error_t status = dev->buf_mgr_->AllocateBuffers(num_descriptors, descriptors,
                                                            out_buffers);
  
    return status;
 }

buf_mgr_是一个BufferManager对象,写到这里就不准备往下看了,能力不足,等到驱动对内存分配完毕之后还需要调用GraphicBufferMapperimportBuffer函数进一步处理handle才能使用,importBuffer最终也会调到HAL层。
到此还是不知道GraphicBuffer内存具体是怎么分配的,但我们了解了从framework到HAL的流程。

总结一下:

  1. Gralloc2Allocator初始化中会获取IAllocator.hal的HIDL client端,通过client端调用allocate函数。
  2. 接着调到IAllocator.hal具体实现AllocatorImpl中。
  3. AllocatorImpl初始化时会加载Gralloc模块,用的是gralloc1.h,并创建Gralloc1Hal,具体实现是Gralloc1HalImpl对象。
  4. Gralloc1HalImplinitWithModule会打开Gralloc下的具体设备,这个设备是GrallocImpl,这是gralloc1_device_t子类。
  5. GrallocImpl中实现了gralloc1.h的函数,是通过调用其内部GetFunction函数给gralloc1.h的函数指针赋值的。
  6. GrallocImpl有一个BufferManager,用来管理Buffer,负责具体的buffer内存分配。
  • 10
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值