概述
Surfaceflinger的主要工作就是负责把上层传递下来的各个不同的layer进行composition。
Android从4.1之后,支持多种显示设备,如HDMI,WIFIDisplay等,并使用Display对象对这些设备进行抽象,同时,对 SurfaceFlinger进行了一次大的调整,用于对每个Display构建起对应的layerlist
每个Display有一个layerstack,每个layer也有一个layerstack,若要指定一个layer显示到特定的display上,必须将其layerstack设置成display的layerstack一致才可以显示
在layer排序的时候,首先是通过layerstack进行筛选,接着是按照z-index对layer进行排序,最后按照sequence排序
SurfaceFliner类和Client类
SurfaceFliner实现了具体的Composition的服务,而每个具有UI的APP都需要SurfaceFlinger去渲染,这些APP可以通过Client的一些接口来调用SurfaceFlinger来实现。Client是APP在SurfaceFlinger服务端的映射。
<span style="background-color: rgb(254, 254, 254);"> status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
{
/*
* createSurface must be called from the GL thread so that it can
* have access to the GL context.
*/
class MessageCreateLayer : public MessageBase {
SurfaceFlinger* flinger;
Client* client;
sp<IBinder>* handle;
sp<IGraphicBufferProducer>* gbp;
status_t result;
const String8& name;
uint32_t w, h;
PixelFormat format;
uint32_t flags;
public:
MessageCreateLayer(SurfaceFlinger* flinger,
const String8& name, Client* client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp)
: flinger(flinger), client(client),
handle(handle), gbp(gbp),
name(name), w(w), h(h), format(format), flags(flags) {
}
status_t getResult() const { return result; }
virtual bool handler() {
result = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);</span><span style="background-color: rgb(102, 255, 255);">//调用SurfaceFlinger createLayer</span><span style="background-color: rgb(254, 254, 254);">
return true;
}
};
sp<MessageBase> msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast<MessageCreateLayer*>( msg.get() )->getResult();
}</span>
CreateLayer过程
<span style="color:#333333;">status_t SurfaceFlinger::createLayer(
const String8& name,
const sp<Client>& client,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp)
{
//ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
if (int32_t(w|h) < 0) {
ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
int(w), int(h));
return BAD_VALUE;
}
status_t result = NO_ERROR;
sp<Layer> layer;
switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
case ISurfaceComposerClient::eFXSurfaceNormal:
result = </span><span style="color:#3366ff;"><strong>createNormalLayer</strong></span><span style="color:#333333;">(client,
name, w, h, flags, format,
handle, gbp, &layer);
break;
case ISurfaceComposerClient::eFXSurfaceDim:
result = </span><span style="color:#3366ff;"><strong>createDimLayer</strong></span><span style="color:#333333;">(client,
name, w, h, flags,
handle, gbp, &layer);
break;
default:
result = BAD_VALUE;
break;
}
if (result == NO_ERROR) {
addClientLayer(client, *handle, *gbp, layer);
setTransactionFlags(eTransactionNeeded);
}
return result;
}
</span>
这个函数很清晰,主要是调用createNormalLayer和createDimLayer去创建不同的layer。先看看createNormalLayer的实现
status_t SurfaceFlinger::<strong>createNormalLayer</strong>(const sp<Client>& client,这要是创建一个layer对象
const String8& name, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format,
sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
// initialize the surfaces
switch (format) {
case PIXEL_FORMAT_TRANSPARENT:
case PIXEL_FORMAT_TRANSLUCENT:
format = PIXEL_FORMAT_RGBA_8888;
break;
case PIXEL_FORMAT_OPAQUE:
#ifdef NO_RGBX_8888
format = PIXEL_FORMAT_RGB_565;
#else
format = PIXEL_FORMAT_RGBX_8888;
#endif
break;
}
#ifdef NO_RGBX_8888
if (format == PIXEL_FORMAT_RGBX_8888)
format = PIXEL_FORMAT_RGBA_8888;
#endif
*outLayer = new <strong>Layer</strong>(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
*handle = (*outLayer)->getHandle();
*gbp = (*outLayer)->getBufferQueue();
}
ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
return err;
}
<span style="color:#333333;">Layer::</span><strong style="color: rgb(51, 51, 51);">Layer</strong><span style="color:#333333;">(SurfaceFlinger* flinger, const sp<Client>& client,
const String8& name, uint32_t w, uint32_t h, uint32_t flags)
: contentDirty(false),
sequence(uint32_t(android_atomic_inc(&sSequence))),
mFlinger(flinger),
mTextureName(-1U),
mPremultipliedAlpha(true),
mName("unnamed"),
mDebug(false),
mFormat(PIXEL_FORMAT_NONE),
mGLExtensions(GLExtensions::getInstance()),
mOpaqueLayer(true),
mTransactionFlags(0),
mQueuedFrames(0),
mCurrentTransform(0),
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mCurrentOpacity(true),
mRefreshPending(false),
mFrameLatencyNeeded(false),
mFiltering(false),
mNeedsFiltering(false),
mSecure(false),
mProtectedByApp(false),
mHasSurface(false),
mClientRef(client)
{
mCurrentCrop.makeInvalid();
glGenTextures(1, &mTextureName);
uint32_t layerFlags = 0;
if (flags & ISurfaceComposerClient::eHidden)
layerFlags = layer_state_t::eLayerHidden;
if (flags & ISurfaceComposerClient::eNonPremultiplied)
mPremultipliedAlpha = false;
mName = name;
mCurrentState.active.w = w;
mCurrentState.active.h = h;
mCurrentState.active.crop.makeInvalid();
mCurrentState.z = 0;
mCurrentState.alpha = 0xFF;
</span><strong><span style="color:#333333;">mCurrentState.layerStack = 0;</span><span style="color:#3366ff;">//初始化layer的时候,layerstack默认设置为0</span></strong><span style="color:#333333;">
mCurrentState.flags = layerFlags;
mCurrentState.sequence = 0;
mCurrentState.transform.set(0, 0);
mCurrentState.requested = mCurrentState.active;
// drawing state & current state are identical
mDrawingState = mCurrentState;
}</span>
Layer顺序相关的信息
sequence(uint32_t(android_atomic_inc(&sSequence))), <span style="color:#3366ff;">//为每一个layre设置唯一且递增的序列号</span>着三个变量决定了layer之间的顺序。
mCurrentState.z = 0;
mCurrentState.layerStack = 0;
1)首先是layerstack,它可以看成是组的含义,不同的layerstack对应的layer互不干扰。
SurfaceFlinger中有一个DisplayDevice类,它用来表示设备,可以是hdmi也可以是wifiDisplay DisplayDevice里也有个mLayerStack,进行composition的时候,只有和这个device的layerstack相等的layer才可以显示到这个设备上。
SurfaceFlinger中有一个DisplayDevice类,它用来表示设备,可以是hdmi也可以是wifiDisplay DisplayDevice里也有个mLayerStack,进行composition的时候,只有和这个device的layerstack相等的layer才可以显示到这个设备上。
2)第二个值是z,也就是z-order,表示z轴上的顺序,数字越大,表示越在上面
3)第三个是sequence,由于mSequence是一个static变量,所以递加的效果是为每个layer设置一个唯一且递增的序列号
创建layer之后,createLayer会调用addClientLayer把这个layer添加到当前状态信息mCurrentState中去,
void SurfaceFlinger::addClientLayer(const sp<Client>& client,这里,layerSortedByZ非常重要,SurfaceFlinger真正渲染的时候就是靠它来知道哪个layer在哪个layer下的。add方法负责将layer放到对应的位置(通过二分查找找到应该插入的位置)
const sp<IBinder>& handle,
const sp<IGraphicBufferProducer>& gbc,
const sp<Layer>& lbc)
{
// attach this layer to the client
client->attachLayer(handle, lbc);
// add this layer to the current state list
Mutex::Autolock _l(mStateLock);
mCurrentState.<strong>layersSortedByZ</strong>.add(lbc);
mGraphicBufferProducerList.add(gbc->asBinder());
}
<span style="background-color: rgb(254, 254, 254);">ssize_t SortedVectorImpl::add(const void* item)
{
size_t order;
ssize_t index = _indexOrderOf(item, &order);</span><strong style="background-color: rgb(255, 255, 255);"><span style="color:#3366ff;">//查找插入位置</span></strong><span style="background-color: rgb(254, 254, 254);">
if (index < 0) {
index = VectorImpl::insertAt(item, order, 1);
} else {
index = VectorImpl::replaceAt(item, index);
}
return index;
}</span>
<span style="font-family:Helvetica Neue, Helvetica, Tahoma, Arial, STXihei, Microsoft YaHei, 微软雅黑, sans-serif;"><span style="font-size: 16px; line-height: 27.2px;">ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const{ // binary search 二分查找法查找插入位置 ssize_t err = NAME_NOT_FOUND; ssize_t l = 0; ssize_t h = size()-1; ssize_t mid; const void* a = arrayImpl(); const size_t s = itemSize(); while (l <= h) { mid = l + (h - l)/2; const void* const curr = reinterpret_cast<const char *>(a) + (mid*s); const int c = do_compare(curr, item);</span></span><span style="color:#3366ff;"><strong>//比较主要依据的地方</strong></span><span style="font-family:Helvetica Neue, Helvetica, Tahoma, Arial, STXihei, Microsoft YaHei, 微软雅黑, sans-serif;"><span style="font-size: 16px; line-height: 27.2px;"> if (c == 0) { err = l = mid; break; } else if (c < 0) { l = mid + 1; } else { h = mid - 1; } } if (order) *order = l; return err;}</span></span>
do_compare方法是比较的依据,比较layerstack,再比较z-order,最后比较sequence
int SurfaceFlinger::LayerVector::do_compare(const void* lhs,但是到现在为止,layerstack和z都是初始化的0,初始化的时候只是根据sequence将layer放到layersSortedByZ而已,其实顺序还是没有设置。
const void* rhs) const
{
<strong>// sort layers per layer-stack, then by z-order and finally by sequence</strong>
const sp<Layer>& l(*reinterpret_cast<const sp<Layer>*>(lhs));
const sp<Layer>& r(*reinterpret_cast<const sp<Layer>*>(rhs));
uint32_t ls = l->currentState().layerStack;
uint32_t rs = r->currentState().layerStack;
if (ls != rs)
return ls - rs;
uint32_t lz = l->currentState().z;
uint32_t rz = r->currentState().z;
if (lz != rz)
return lz - rz;
return l->sequence - r->sequence;
}
实例
现在来看看从哪里进行了设置,以bootanimation为例(开机动画)
// create the native surface
sp<SurfaceControl> control = session()->createSurface(String8("BootAnimation"),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
SurfaceComposerClient::openGlobalTransaction();
<strong>control->setLayer(0x40000000);</strong>
SurfaceComposerClient::closeGlobalTransaction();
前面的过程就是createSurface的过程。下面就是setLayer了,来了解下0x40000000的设置
status_t SurfaceControl::<strong>setLayer</strong>(int32_t layer) {
status_t err = validate();
if (err < 0) return err;
const sp<SurfaceComposerClient>& client(mClient);
return client-><strong>setLayer</strong>(mHandle, layer);
}
status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) {
return getComposer().<strong>setLayer</strong>(this, id, z);
}
status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, int32_t z) {
Mutex::Autolock _l(mLock);
layer_state_t* s = <em><strong>getLayerStateLocked</strong></em>(client, id);
if (!s)
return BAD_INDEX;
<strong>s->what |= layer_state_t::eLayerChanged;//<span style="color:#3333ff;">下面</span></strong><pre class="prettyprint perl" style="padding: 0.3em; font-family: Monaco, Menlo, Consolas, 'Courier New', monospace; border-radius: 4px; margin-top: 0px; margin-bottom: 1.5em; line-height: 1.5em; word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgba(0, 0, 0, 0.14902); overflow-y: auto; display: inline !important; background-color: rgb(246, 246, 246);"><span style="color:#3333ff;">setClientStateLocked中会判断</span>
通过这个判断layer是否修改 s->z = z; return NO_ERROR;} 从这里可以看到layer的设置最终修改了layer_state_t *s 的z,而这个s是通过getLayerStateLocked获得的
layer_state_t* Composer::<strong>getLayerStateLocked</strong>(但是也就是改了这里的值,没有真正起效呢 回到bootanimation的代码,我们发现,后面紧接着是 closeGlobalTransaction,来看看这个方法都做了什么吧 ^_^
const sp<SurfaceComposerClient>& client, const sp<IBinder>& id) {
ComposerState s;
s.client = client->mClient;
s.state.surface = id;
ssize_t index = mComposerStates.indexOf(s);<span style="color:#3366ff;">//原来是从这里找到的</span><img alt="微笑" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/smile.gif" />
if (index < 0) {
// we don't have it, add an initialized layer_state to our list
index = mComposerStates.add(s);
}
ComposerState* const out = mComposerStates.editArray();
return &(out[index].state);
}
void SurfaceComposerClient::<strong>closeGlobalTransaction</strong>(bool synchronous) {
Composer::closeGlobalTransaction(synchronous);
}
<span style="color:#333333;">void Composer::</span><strong style="color: rgb(51, 51, 51);">closeGlobalTransactionImpl</strong><span style="color:#333333;">(bool synchronous) {mComposerStates被赋值给transaction,然后通过setTransactionState传递下去
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
Vector<ComposerState> transaction;
Vector<DisplayState> displayTransaction;
uint32_t flags = 0;
{ // scope for the lock
Mutex::Autolock _l(mLock);
mForceSynchronous |= synchronous;
if (!mTransactionNestCount) {
ALOGW("At least one call to closeGlobalTransaction() was not matched by a prior "
"call to openGlobalTransaction().");
} else if (--mTransactionNestCount) {
return;
}
<strong><em>transaction = mComposerStates;</em></strong> </span><span style="color:#3366ff;"><strong>//在上面修改修改了z值</strong></span><span style="color:#333333;">
mComposerStates.clear();</span><span style="color:#333333;">
displayTransaction = mDisplayStates;
mDisplayStates.clear();
if (mForceSynchronous) {
flags |= ISurfaceComposer::eSynchronous;
}
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}
if (mTransition) {
flags |= ISurfaceComposer::eTransition;
}
if (mOrientationEnd) {
flags |= ISurfaceComposer::eOrientationEnd;
}
mForceSynchronous = false;
mAnimation = false;
}
sm-><strong>setTransactionState</strong>(<em><strong>transaction</strong></em>, displayTransaction, flags);
}</span>
<span style="color:#333333;">void SurfaceFlinger::</span><strong style="color: rgb(51, 51, 51);">setTransactionState</strong><span style="color:#333333;">(
const Vector<ComposerState>& state,
const Vector<DisplayState>& displays,
uint32_t flags)
{
......
count = state.size();
for (size_t i=0 ; i<count ; i++) {
const ComposerState& s(state[i]);
// Here we need to check that the interface we're given is indeed
// one of our own. A malicious client could give us a NULL
// IInterface, or one of its own or even one of our own but a
// different type. All these situations would cause us to crash.
//
// NOTE: it would be better to use RTTI as we could directly check
// that we have a Client*. however, RTTI is disabled in Android.
if (s.client != NULL) {
sp<IBinder> binder = s.client->asBinder();
if (binder != NULL) {
String16 desc(binder->getInterfaceDescriptor());
if (desc == ISurfaceComposerClient::descriptor) {
sp<Client> client( static_cast<Client *>(s.client.get()) );
transactionFlags |= </span><strong style="color: rgb(51, 51, 51);">setClientStateLocked</strong><span style="color:#333333;">(client, s.state);</span><span style="color:#3333ff;"><strong>//调用setClientStateLocked</strong></span><span style="color:#333333;">
}
}
}
}
......
}</span>
uint32_t SurfaceFlinger::<strong>setClientStateLocked</strong>( const sp<Client>& client, const layer_state_t& s){ uint32_t flags = 0; sp<Layer> layer(client->getLayerUser(s.surface)); if (layer != 0) { const uint32_t what = s.what; if (what & layer_state_t::ePositionChanged) { if (layer->setPosition(s.x, s.y)) flags |= eTraversalNeeded; } if (what & layer_state_t::eLayerChanged) { <strong><span style="color:#3333ff;">//s.what在上面<span style="line-height: 27.2px; font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif;">Composer::setLayer修改过了</span></span></strong> // NOTE: index needs to be calculated before we update the state ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer); if (layer->setLayer(s.z)) {<span style="color: rgb(51, 51, 255); font-weight: bold; line-height: 27.2px; font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif;">//s.z在上面</span><span style="color: rgb(51, 51, 255); line-height: 27.2px; font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif;"><strong>Composer::setLayer修改过了,调用layer的setLayer真正修改layer的layerStack值</strong></span> mCurrentState.layersSortedByZ.removeAt(idx); mCurrentState.layersSortedByZ.add(layer); // we need traversal (state changed) // AND transaction (list changed) <strong>flags |= eTransactionNeeded|eTraversalNeeded;</strong> } } ......}
bool Layer::setLayer(uint32_t z) {可以看到,只要设置的z值和之前的不同,setLayer就会返回true。
if (mCurrentState.z == z)
return false;
mCurrentState.sequence++;
mCurrentState.z = z;
setTransactionFlags(eTransactionNeeded);
return true;
}
然后mCurrentState.layersSortedByZ.removeAt和mCurrentState.layersSortedByZ.add就会被执行,这时,layer将会按照z真正意义上插入到layersSortedByZ中。
到这里,layer的真正z-order就确定好了。