SurfaceFlinger的渲染客户端Surface初始化
Posted 白嫩豆腐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SurfaceFlinger的渲染客户端Surface初始化相关的知识,希望对你有一定的参考价值。
关于SurfaceFlinger他大部分都是三层架构
SurfaceFlinger是针对整个系统,
用户类 | 本地binder | 服务端binder | |
---|---|---|---|
ComposerService | BpSurfaceComposer | SurfaceFlinger | |
SurfaceComposerClient | BpSurfaceComposerClient | Client | |
Surface | SurfaceControl | IBinder | Layer |
这里数据结构三层,是方便管理,一个系统只有一个SurfaceFlinger。
每个应用拥有 一个SurfaceComposerClient,
每个窗体或者surface对应一个layer。
前两个业务逻辑相对简单,主要维护数据。而Surface,是比较复杂的,主要通过layer生成共享内存的管理类。然后交给程序端渲染。
高版本的android主要通过生产消费者模式。对于客户程序其实是一个生产者(Producer)。而服务端则是一个消费端(交个hw层渲染)。
下面我们主要分析一下surface以及layer的具体实现类。
Layer真实类型为BufferQueueLayer
我们从SurfaceComposerClientcreat出Surface这个过程追踪一下代码。了解一下过程。
2.1 用户端请求
这个过程相对简单,开始是通过调用SurfaceComposerClient的函数
sp<SurfaceControl> control = session()->createSurface(String8("uitest"),
resolution.getWidth(), resolution.getHeight(), PIXEL_FORMAT_RGB_565);
sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
PixelFormat format, uint32_t flags,
SurfaceControl* parent,
LayerMetadata metadata,
uint32_t* outTransformHint)
sp<SurfaceControl> s;
createSurfaceChecked(name, w, h, format, &s, flags, parent, std::move(metadata),
outTransformHint);
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,
uint32_t* outTransformHint)
sp<SurfaceControl> sur;
status_t err = mStatus;
if (mStatus == NO_ERROR)
sp<IBinder> handle;
sp<IBinder> parentHandle;
sp<IGraphicBufferProducer> gbp;
if (parent != nullptr)
parentHandle = parent->getHandle();
uint32_t transformHint = 0;
err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
&handle, &gbp, &transformHint);
if (outTransformHint)
*outTransformHint = transformHint;
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR)
*outSurface = new SurfaceControl(this, handle, gbp, transformHint);
return err;
这里其实相对加单,就是调用client的createSurface,因为client类型是BpSurfaceComposerClient,其实这里客户端已经完成了任务,已经通过binder把请求发送给服务端的Client中了。下面我们进入第二阶段的代码阅读。他主要是服务端构造Layer,生成共享buffer,实现卡进程的数据(帧数据)共享
2.2 服务端处理
处理端其实到了Client.cpp的函数,其实相对比较简单,直接交给SurfaceFlinger处理:
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, uint32_t* outTransformHint)
// We rely on createLayer to check permissions.
return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
parentHandle, nullptr, outTransformHint);
具体代码如下:
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,
uint32_t* outTransformHint)
sp<Layer> layer;
switch (flags & ISurfaceComposerClient::eFXSurfaceMask)
case ISurfaceComposerClient::eFXSurfaceBufferQueue:
result = createBufferQueueLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), format, handle, gbp, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceBufferState:
result = createBufferStateLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), handle, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceEffect:
// check if buffer size is set for color layer.
if (w > 0 || h > 0)
ALOGE("createLayer() failed, w or h cannot be set for color layer (w=%d, h=%d)",
int(w), int(h));
return BAD_VALUE;
result = createEffectLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), handle, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceContainer:
// check if buffer size is set for container layer.
if (w > 0 || h > 0)
ALOGE("createLayer() failed, w or h cannot be set for container layer (w=%d, h=%d)",
int(w), int(h));
return BAD_VALUE;
result = createContainerLayer(client, std::move(uniqueName), w, h, flags,
std::move(metadata), handle, &layer);
break;
default:
result = BAD_VALUE;
break;
//保存layer,为了surfaceflinger维护layer
result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
addToCurrentState, outTransformHint);
if (result != NO_ERROR)
return result;
//不重要
mInterceptor->saveSurfaceCreation(layer);
//binder相关
setTransactionFlags(eTransactionNeeded);
return result;
这段代码其实业务比较简单,通过特定的flag,生成不同的layer,然后配置layer,然后调用binder。关键是传入的flag。我们直接通过最简单的,阅读BufferQueueLayer相关代码。
status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, std::string name,
uint32_t w, uint32_t h, uint32_t flags,
LayerMetadata metadata, PixelFormat& format,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp,
sp<Layer>* outLayer)
......
sp<BufferQueueLayer> layer;
LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
args.textureName = getNewTexture();
// Grab the SF state lock during this since it's the only safe way to access
// RenderEngine when creating a BufferLayerConsumer
// TODO: Check if this lock is still needed here
Mutex::Autolock lock(mStateLock);
layer = getFactory().createBufferQueueLayer(args);
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;
mFactory具体类型为DefaultFactory。具体代码就比较加单了:
sp<BufferQueueLayer> DefaultFactory::createBufferQueueLayer(const LayerCreationArgs& args)
return new BufferQueueLayer(args);
BufferQueueLayer 构造函数不算复杂,关键是onFirstRef的功能:
void BufferQueueLayer::onFirstRef()
BufferLayer::onFirstRef();
// Creates a custom BufferQueue for SurfaceFlingerConsumer to use
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
mFlinger->getFactory().createBufferQueue(&producer, &consumer, true);
mProducer = mFlinger->getFactory().createMonitoredProducer(producer, mFlinger, this);
mConsumer =
mFlinger->getFactory().createBufferLayerConsumer(consumer, mFlinger->getRenderEngine(),
mTextureName, this);
mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mContentsChangedListener = new ContentsChangedListener(this);
mConsumer->setContentsChangedListener(mContentsChangedListener);
mConsumer->setName(String8(mName.data(), mName.size()));
// BufferQueueCore::mMaxDequeuedBufferCount is default to 1
if (!mFlinger->isLayerTripleBufferingDisabled())
mProducer->setMaxDequeuedBufferCount(2);
这里通过SurfaceFlinger的factory生成消费者和生产者,供给客户程序调用,我们稍微观察一下:
sp<IGraphicBufferProducer> DefaultFactory::createMonitoredProducer(
const sp<IGraphicBufferProducer>& producer, const sp<SurfaceFlinger>& flinger,
const wp<Layer>& layer)
return new MonitoredProducer(producer, flinger, layer);
sp<BufferLayerConsumer> DefaultFactory::createBufferLayerConsumer(
const sp<IGraphicBufferConsumer>& consumer, renderengine::RenderEngine& renderEngine,
uint32_t textureName, Layer* layer)
return new BufferLayerConsumer(consumer, renderEngine, textureName, layer);
其实这里已经介绍完毕,最终会吧BufferQueueLayer传入到客户端,生成control。最终封装成Surface。用于绘制内容。
2.3 服务端收到回复处理
客户端处理基本上就是通过binder返回的数据,构造一个SurfaceControl,这里没有特别复杂的,核心是通过SurfaceControl获取surface。
sp<Surface> SurfaceControl::getSurface() const
Mutex::Autolock _l(mLock);
if (mSurfaceData == nullptr)
return generateSurfaceLocked();
return mSurfaceData;
类似与一个单利。
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;
其实这里就比较简单了,关键是mGraphicBufferProducer,其实是Layer中的一个一个变量,传入到客户端了。
后记
下一篇着重分析一下mGraphicBufferProducer,的数据结构,以及如何实现跨进程数据传输的,如何吧我们的buffer交到surfaceflnger的,最后一片大概分析一下hw层,了解一下数据下传的过程,整个androidUI相关基本算是搞定。如果有机会再开一篇,介绍一下activity的窗口如何显示。
以上是关于SurfaceFlinger的渲染客户端Surface初始化的主要内容,如果未能解决你的问题,请参考以下文章
SurfaceFlinger的渲染客户端Surface初始化
SurfaceFlinger的渲染客户端Surface初始化
SurfaceFlinger系列01--Android应用与SurfaceFlinger的连接过程