Android显示系统(01)- 架构分析
Android显示系统(02)- OpenGL ES - 概述
Android显示系统(03)- OpenGL ES - GLSurfaceView的使用
Android显示系统(04)- OpenGL ES - Shader绘制三角形
Android显示系统(05)- OpenGL ES - Shader绘制三角形(使用glsl文件)
Android显示系统(06)- OpenGL ES - VBO和EBO和VAO
Android显示系统(07)- OpenGL ES - 纹理Texture
Android显示系统(08)- OpenGL ES - 图片拉伸
Android显示系统(09)- SurfaceFlinger的使用
Android显示系统(10)- SurfaceFlinger内部结构
Android显示系统(11)- 向SurfaceFlinger申请Surface
Android显示系统(12)- 向SurfaceFlinger申请Buffer
Android显示系统(13)- 向SurfaceFlinger提交Buffer
一、前言:
前面已经和SurfaceFlinger
建立好了连接,那么,本章介绍下如何去向SurfaceFlinger
申请我们的画布(也就是Surface)。
二、获取Surface流程:
上面创建好了Client,也就是创建好了连接,我们要绘制一张图片,首先得拿到画布,这个由CreateSurface
完成:
status_t BootAnimation::readyToRun() {// 。。。// 创建SurfaceControl, 参数指定名称 ("BootAnimation")、宽度、高度和像素格式 (PIXEL_FORMAT_RGB_565)sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);SurfaceComposerClient::Transaction t;t.setLayer(control, 0x40000000).apply();// 获得对应的Surface(画布)sp<Surface> s = control->getSurface();// 。。。
}
可以看出,先获取SurfaceControl
,然后从SurfaceControl
当中取出了Surface
,那么,这个API调用,后面都有谁在配合呢?
1、APP侧开始请求:
这个session()里面其实就是返回一个mSession
,我们都知道mSession
是sp<SurfaceComposerClient>
类型,进去看看:
sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,PixelFormat format, uint32_t flags,SurfaceControl* parent,LayerMetadata metadata) {sp<SurfaceControl> s;createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata));return s;
}
再进去看看:
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,PixelFormat format,sp<SurfaceControl>* outSurface, uint32_t flags,SurfaceControl* parent,LayerMetadata metadata) {sp<SurfaceControl> sur;status_t err = mStatus;if (mStatus == NO_ERROR) {sp<IBinder> handle; // Surfacesp<IBinder> parentHandle;sp<IGraphicBufferProducer> gbp; // SF端Layer的生产者对象if (parent != nullptr) {parentHandle = parent->getHandle();}// 这个mClienterr = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),&handle, &gbp);ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));if (err == NO_ERROR) {// 创建SurfaceControl*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);}}return err;
}
前面说过,这个mClient
其实就是BpSurfaceComposer
,所以,这个函数就是先远程调用SF获取了一个Surface(通过handle返回),并且呢,用一个SurfaceControl
将这个Surface
持有并管理起来。
BpSurfaceComposerClient
当中发起远程调用:
status_t createSurface(const String8& name, uint32_t width, uint32_t height, PixelFormat format,uint32_t flags, const sp<IBinder>& parent, LayerMetadata metadata,sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp) override {return callRemote<decltype(&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE,name, width, height,format, flags, parent,std::move(metadata),handle, gbp);}
记住这个Tag::CREATE_SURFACE
,发起Binder远程调用之后,SF侧就会根据这个id来处理。
2、SurfaceFlinger侧响应:
- 简单调用逻辑传递:
binder调用部分省略,参考上一章的createConnection
,然后就来到了:
status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,uint32_t flags, const sp<IBinder>& parentHandle,LayerMetadata metadata, sp<IBinder>* handle,sp<IGraphicBufferProducer>* gbp) {// We rely on createLayer to check permissions.return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,parentHandle);
}
这就相当于什么?相当于客户端调用了一个createSurface,到了服务端调用了Client::createSurface
,里面进行了Layer
的创建。
status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,uint32_t h, PixelFormat format, uint32_t flags,LayerMetadata metadata, sp<IBinder>* handle,sp<IGraphicBufferProducer>* gbp,const sp<IBinder>& parentHandle,const sp<Layer>& parentLayer) {sp<Layer> layer;//...switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {// 就是普通Surfacecase ISurfaceComposerClient::eFXSurfaceBufferQueue:result = createBufferQueueLayer(client, uniqueName, w, h, flags, std::move(metadata),format, handle, gbp, &layer);break;case ISurfaceComposerClient::eFXSurfaceBufferState:result = createBufferStateLayer(client, uniqueName, w, h, flags, std::move(metadata),handle, &layer);break;case ISurfaceComposerClient::eFXSurfaceColor:// 。。。case ISurfaceComposerClient::eFXSurfaceContainer:// 。。。default:result = BAD_VALUE;break;}if (primaryDisplayOnly) {layer->setPrimaryDisplayOnly();}bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,addToCurrentState);if (result != NO_ERROR) {return result;}mInterceptor->saveSurfaceCreation(layer);setTransactionFlags(eTransactionNeeded);return result;
}
对于上面的switch…case,我们为啥走第一个呢?我给你加了注释:
enum { // (keep in sync with Surface.java)// 表示 Surface 默认状态是隐藏的, 用于需要控制 Surface 显示/隐藏状态的情况,例如临时用来后台渲染内容的 SurfaceeHidden = 0x00000004,// 指示在销毁表面时是否销毁后备缓冲区。不适合需要保留屏幕内容的情况eDestroyBackbuffer = 0x00000020,// 表示 Surface 是安全的,意味着内容只能显示在安全的显示器上(如受保护的 HDMI 输出)eSecure = 0x00000080,// 表示创建的表面使用非预乘的像素格式eNonPremultiplied = 0x00000100,// 如果设置了该标志,Surface 将忽略 alpha 通道,像素总是完全不透明的eOpaque = 0x00000400,// Surface 内容由应用保护。内容通常是敏感数据,应用负责其生命周期eProtectedByApp = 0x00000800,// 表示 Surface 受到 DRM(数字版权管理)保护,通常通过硬件实现。eProtectedByDRM = 0x00001000,// 表示 Surface 用作光标窗口。系统级别的输入指针,比如鼠标指针。eCursorWindow = 0x00002000,// 表明这是一个普通的 BufferQueue Surface(默认设置,无附加特性)。创建普通的 Surface。eFXSurfaceBufferQueue = 0x00000000,// 表示这是一个颜色缓冲区的 Surface,可能用于特殊效果(如着色器)。eFXSurfaceColor = 0x00020000,// 允许使用不同的 buffer 管理策略(如摆脱传统的 BufferQueue 行为)。eFXSurfaceBufferState = 0x00040000,// 表示这是一个 "容器 Surface",用来包裹其他子 Surface。窗口管理器或复杂 Layer。eFXSurfaceContainer = 0x00080000,// 一个掩码 (mask),表示 eFXSurface* 类 Surface 的通用标志。eFXSurfaceMask = 0x000F0000,};
显然,我们就是一个普通的surface;
-
创建Layer的过程:
status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, const String8& name,uint32_t w, uint32_t h, uint32_t flags,LayerMetadata metadata, PixelFormat& format,sp<IBinder>* handle,sp<IGraphicBufferProducer>* gbp,sp<Layer>* outLayer) {// initialize the surfacesswitch (format) {case PIXEL_FORMAT_TRANSPARENT:case PIXEL_FORMAT_TRANSLUCENT:format = PIXEL_FORMAT_RGBA_8888;break;case PIXEL_FORMAT_OPAQUE:format = PIXEL_FORMAT_RGBX_8888;break;}// 创建了一个Layersp<BufferQueueLayer> layer = getFactory().createBufferQueueLayer(LayerCreationArgs(this, client, name, w, h, flags, std::move(metadata)));status_t err = layer->setDefaultBufferProperties(w, h, format);if (err == NO_ERROR) {*handle = layer->getHandle();*gbp = layer->getProducer();*outLayer = layer;}ALOGE_IF(err, "createBufferQueueLayer() failed (%s)", strerror(-err));return err; }
看到创建Layer成功之后,便将Layer的handle,以及Layer的
BufferQueueProducer
返回,同时,也将layer本身返回给outLayer。那么,这个工厂是如何创建这个Layer的呢?
看看文件
native\services\surfaceflinger\SurfaceFlingerFactory.cpp
中:sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) override {return new BufferQueueLayer(args); }
就是new了一个,返回而已,我们第一个引用Layer时候会发生什么?
void BufferQueueLayer::onFirstRef() {BufferLayer::onFirstRef();// Creates a custom BufferQueue for SurfaceFlingerConsumer to usesp<IGraphicBufferProducer> producer;sp<IGraphicBufferConsumer> consumer;// 创建BufferQueue的时候,里面会创建生产者和消费者BufferQueue::createBufferQueue(&producer, &consumer, true);// 将消费者做一次封装mProducer = new MonitoredProducer(producer, mFlinger, this);{// Grab the SF state lock during this since it's the only safe way to access RenderEngine// 同样,将生产者做一次封装Mutex::Autolock lock(mFlinger->mStateLock);mConsumer =new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);}mConsumer->setConsumerUsageBits(getEffectiveUsage(0));mConsumer->setContentsChangedListener(this);mConsumer->setName(mName);// BufferQueueCore::mMaxDequeuedBufferCount is default to 1if (!mFlinger->isLayerTripleBufferingDisabled()) {mProducer->setMaxDequeuedBufferCount(2);}if (const auto display = mFlinger->getDefaultDisplayDevice()) {updateTransformHint(display);} }
主要就是创建了一个
BufferQueue
和Producer
和Consumer
。 -
刚才看到生产者和消费者都继承自
IGraphicBufferProducer
,我们看下:- APP这边的
BpGraphicBufferProducer
和 Native那边的Client的Layer成员的mProducer
,都继承自IGraphicBufferProducer
; - 不过Native最终使用的是
IGraphicBufferProducer
派生的BnGraphicBufferProducer
派生的BnBufferQueueProducer
;
- APP这边的
于是,我们再回去看看APP侧如何处理返回的这些东西。
3、APP侧处理返回值:
直接看代码:
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,PixelFormat format,sp<SurfaceControl>* outSurface, uint32_t flags,SurfaceControl* parent,LayerMetadata metadata) {sp<SurfaceControl> sur;status_t err = mStatus;if (mStatus == NO_ERROR) {sp<IBinder> handle; // Surfacesp<IBinder> parentHandle;sp<IGraphicBufferProducer> gbp; // SF端Layer的生产者对象if (parent != nullptr) {parentHandle = parent->getHandle();}// 这个mClienterr = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),&handle, &gbp);ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));if (err == NO_ERROR) {// 创建SurfaceControl*outSurface = new SurfaceControl(this, handle, gbp, true /* owned */);}}return err;
}
发现将创建好的handle、gdp全都作为参数用来创建SurfaceControl
了。进去看看:
SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client,const sp<IBinder>& handle,const sp<IGraphicBufferProducer>& gbp,bool owned): mClient(client), mHandle(handle), mGraphicBufferProducer(gbp), mOwned(owned)
{
}
发现构造函数直接将gbp保存到mGraphicBufferProducer
当中了。啥时候用呢?
当你从SurfaceControl
获取Surface的时候:
sp<Surface> SurfaceControl::getSurface() const
{Mutex::Autolock _l(mLock);if (mSurfaceData == nullptr) {return generateSurfaceLocked();}return mSurfaceData;
}
看看这个generateSurfaceLocked
:
sp<Surface> SurfaceControl::generateSurfaceLocked() const
{// This surface is always consumed by SurfaceFlinger, so the// producerControlledByApp value doesn't matter; using false.mSurfaceData = new Surface(mGraphicBufferProducer, false);return mSurfaceData;
}
发现生成Surface的时候,gbp是入参,也就是说这个Buffer的生产者已经被我们Surface持有了,以后可以通过Surface往SF侧的Layer当中BufferQueue写东西。
三、总结:
至此,Surface获取部分讲解完成,拿到画布之后该往里填数据了吧?