Android7.0 Gralloc模块的加载

很多文章说Gralloc模块是由FramebufferNativewindow在构造函数中加载的,但是在android7.0的代码中没有找到FrameBufferNativewindow类。

通过查看代码,7.0版本,应该是HWComposer模块的构造函数中加载了Gralloc库:

// Load and prepare the FB HAL, which uses the gralloc module.  Sets mFbDev.
int HWComposer::loadFbHalModule()
{
    hw_module_t const* module;

    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
    if (err != 0) {
        ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
        return err;
    }

    return framebuffer_open(module, &mFbDev);
}

 

然后通过open方法打开了Gralloc中的两个设备即fb0和gralloc:

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

int gralloc_device_open(const hw_module_t* module, const char* name,
        hw_device_t** device)
{
    int status = -EINVAL;
    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
        gralloc_context_t *dev;
        dev = (gralloc_context_t*)malloc(sizeof(*dev));

        /* initialize our state here */
        memset(dev, 0, sizeof(*dev));

        /* initialize the procs */
        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version = 0;
        dev->device.common.module = const_cast<hw_module_t*>(module);
        dev->device.common.close = gralloc_close;

        dev->device.alloc   = gralloc_alloc;
        dev->device.free    = gralloc_free;

        *device = &dev->device.common;
        status = 0;
    } else {
        status = fb_device_open(module, name, device);
    }
    return status;
}

 

有一个问题,因为没有找到FrameBufferNativewindow,面向SurfaceFlinger的本地窗口是谁呢?是FramebufferSurface?即:android\frameworks\native\services\surfaceflinger\DisplayHardware\FramebufferSurface.cpp。

还在分析中...,那位朋友知道给指点下!

-----------------------

续:

面向SurfaceFligner的本地窗口也是Surface,跟面向应用程序的Surface是同一类型,只是其中缓冲区的来源不同,面向SurfaceFlinger的Surface对应的缓冲区是从帧缓冲区分配;面向应用程序的Surface对应的缓冲区是从匿名共享内存分配,这也符合应用程序和SurfaceFlinger共享这块缓冲区的特点。

先看面向SurfaceFligner的Surface:

SurfaceFlinger.cpp

void SurfaceFlinger::createDefaultDisplayDevice() {

    sp<IGraphicBufferProducer> producer;

    sp<IGraphicBufferConsumer> consumer;

    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);

    sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,

        token, fbs, producer, mRenderEngine->getEGLConfig(),useWideColorMode);

}

其中FramebufferSurface.cpp的构造函数中,通过BufferQueueConsumer设置了Surface要申请的缓冲区的用途。

FramebufferSurface.cpp

FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp,

        const sp<IGraphicBufferConsumer>& consumer) :ConsumerBase(consumer),...{

    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |

        GRALLOC_USAGE_HW_RENDER |GRALLOC_USAGE_HW_COMPOSER);

}

通过BufferQueueConsumer的函数setConsumerUsageBits来设置USAGE的类型,会保存到BufferQueueCore中的mConsumerUsageBits变量中。

在看DisplayDevice的构造函数:

DisplayDevice.cpp

sp<ANativeWindow> mNativeWindow;

DisplayDevice::DisplayDevice(  const sp<SurfaceFlinger>& flinger,...){

    Surface* surface;

    mNativeWindow = surface = new Surface(producer, false);

    ANativeWindow* const window = mNativeWindow.get();

    EGLSurface eglSurface;

    eglSurface = eglCreateWindowSurface(display, config, window, NULL);

}

先是创建了Surface对象赋值给ANativeWindow类型的指针变量mNativeWindow,然后用其构造一个EglSurface,配置opengl es环境。


在看面向应用程序的Surface:

应用程序端的Surface实际对应了一个layer,

Layer.cpp

void Layer::onFirstRef() {

    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));

}

uint32_t Layer::getEffectiveUsage(uint32_t usage) const
{
    // TODO: should we do something special if mSecure is set?
    if (mProtectedByApp) {
        // need a hardware-protected path to external video sink
        usage |= GraphicBuffer::USAGE_PROTECTED;
    }
    if (mPotentialCursor) {
        usage |= GraphicBuffer::USAGE_CURSOR;
    }
    usage |= GraphicBuffer::USAGE_HW_COMPOSER;
    return usage;
}

通过SurfaceFlingerConsumer间接调用了BufferQueueConsumer的setConsumerUsageBits函数,来设置缓冲区用途。


最后看缓冲区的分配:

BufferQueueProducer.cpp

void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height,

        PixelFormat format, uint64_t usage) {

    uint64_t allocUsage = 0;

    allocUsage = usage | mCore->mConsumerUsageBits;

    sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(

        allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT,

        allocUsage, {mConsumerName.string(), mConsumerName.size()});

}

先获取前面设置的usage,作为GraphicBuffer的参数。

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)
{
    GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
    uint32_t outStride = 0;
    status_t err = allocator.allocate(inWidth, inHeight, inFormat, inLayerCount,
            inUsage, &handle, &outStride, mId,
            std::move(requestorName));
    return err;
}

GraphicBufferAllocator返回的是Gralloc中的Allocator,所以最终完成缓冲区分配的是Gralloc。

gralloc.cpp

static int gralloc_alloc(alloc_device_t* dev,
        int width, int height, int format, int usage,
        buffer_handle_t* pHandle, int* pStride){
    if (usage & GRALLOC_USAGE_HW_FB) {
        err = gralloc_alloc_framebuffer(dev, size, usage, pHandle);
    } else {
        err = gralloc_alloc_buffer(dev, size, usage, pHandle);
    }
}

根据不同的用途,从不同的区域分配内存。

static int gralloc_alloc_framebuffer(alloc_device_t* dev,
        size_t size, int usage, buffer_handle_t* pHandle)
{
    private_module_t* m = reinterpret_cast<private_module_t*>(
            dev->common.module);
    pthread_mutex_lock(&m->lock);
//从帧缓冲区
    int err = gralloc_alloc_framebuffer_locked(dev, size, usage, pHandle);
    pthread_mutex_unlock(&m->lock);
    return err;
}

static int gralloc_alloc_buffer(alloc_device_t* dev,
        size_t size, int /*usage*/, buffer_handle_t* pHandle){
    size = roundUpToPageSize(size);
    //从匿名共享内存
    fd = ashmem_create_region("gralloc-buffer", size);
    if (fd < 0) {
        ALOGE("couldn't create ashmem (%s)", strerror(-errno));
        err = -errno;
    }
    
    return err;
}

帧缓冲区FrameBuffer可以看成是显示设备的抽象,所以往这块缓冲区post数据,就相当于送到了显示设备。

被显示的线段、字符、图形、背景色都会按像素一一存储在Framebuffer中,它是屏幕所显示画面的一个直接映像,也成为光栅,FrameBuffer中的每一个存储单元对应屏幕上的一个像素,整个帧缓存就对应了一帧图像。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值