07.显示系统:第004课_SurfaceFlinger内部机制:第004节_APP申请(lock)Buffer的过程_框架

该小节我们讲解应用程序申请(lock)Buffer的过程,在在这之前,先回顾一下之前三个小节的内容。
在这里插入图片描述

我们知道一个应用程序如果需要去显示界面,
1.他需要用到SurfaceFlinger的服务,与其建立联系,在SurfaceFlinger中产生一个与APP对应的client。
2.然后创建一个Surface,SurfaceFlinger中会存在一个Layer与之对应,并且我们知道,Layer中有生产者与消费者,Surface中的成员mGraphicBufferProducer指向Layer中的生产者。并且Surface中与Layer中的生产者都存在成员mSlots。其mSlots为一个BufferSlot的数组。
3.获得一个Surface中的Buffer:a.查看mSlots中有无空余项。b.如果没有,向生产者申请,生产者也是参看自己的mSlots中有无空余项,如果没有向Graclloc模块申请(实际向匿名控件申请),得到一个句柄fd,这个fd会返回给我们的应用程序(通过binder驱动)。c.应用程序获得fd,使用mmap获得地址。然后这个地址还会放入到mSlots中。

下面是一个详细的流程图,可以从左下角A4处开始观看:
在这里插入图片描述
下面我们开始分析代码,其三个点为核心:
1.Buffer由SurfaceFlinger分配,获得fd,然后返回给应用程序。
2.应用程序接收到fd之后,使用mmap。

源码分析

在应用程序中,存在代码:

	surface->lock(&outBuffer, NULL);

进入surface.cpp找到lock函数:

status_t Surface::lock(
	/*从队列中取出buffer保存到out*/
	status_t err = dequeueBuffer(&out, &fenceFd);
		/*使用代理类,发起跨进程的远程调用,向SurfaceFlinger发起buf申请,导致对方分配内存*/
		status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,reqWidth, reqHeight, reqFormat, reqUsage);
		/*先SurfaceFlinger请求返回文件句柄fd,然后在APP边mmap*/
		result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
	/*把outBuffer赋值给backBuffer(后面的Buffer),一个Surface有多个buf,当我们提交buf之后,buffer变成前面的buf*/
	sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
	/*获得一个虚拟地址vaddr,后续赋值给outBuffer->bits   = vaddr;*/
    status_t res = backBuffer->lockAsync(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,newDirtyRegion.bounds(), &vaddr, fenceFd);
    /*填充buf的地址,在测试程序中可以找到:
    android_memset16((uint16_t*)outBuffer.bits, 0xF800, bpr*outBuffer.height);*/
    outBuffer->bits   = vaddr;

下面节我们将分析:

		/*使用代理类,发起跨进程的远程调用,向SurfaceFlinger发起buf申请,导致对方分配内存*/
		status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,reqWidth, reqHeight, reqFormat, reqUsage);
		/*先SurfaceFlinger请求返回文件句柄fd,然后在APP边mmap*/
		result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);

SurfaceFlinger接收到请求之后,做了什么。

猜你喜欢

转载自blog.csdn.net/weixin_43013761/article/details/88873388