SurfaceControl的创建是在ViewRootImpl中调用requestLayout,最后到WMS的relayoutWindow函数创建SurfaceControl对象。是通过WindowState的WindowStateAnimator对象调用createSurfaceLocked对象创建的。最后再通过outSurface传给ViewRootImpl。
......
SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();//创建SurfaceControl
if (surfaceControl != null) {
outSurface.copyFrom(surfaceControl);//把Surface传给ViewRootImpl
if (SHOW_TRANSACTIONS) Slog.i(TAG,
" OUT SURFACE " + outSurface + ": copied");
} else {
// For some reason there isn't a surface. Clear the
// caller's object so they see the same state.
outSurface.release();
}
......
然后在WindowStateAnimator的createSurfaceLocked中创建SurfaceControl,如下
mSurfaceControl = new SurfaceControl(
mSession.mSurfaceSession,
attrs.getTitle().toString(),
width, height, format, flags);
随后会调用SurfaceControl的设置位置,设置layer等函数,这个我们后面再分析。
SurfaceControl.openTransaction();
try {
mSurfaceX = left;
mSurfaceY = top;
try {
mSurfaceControl.setPosition(left, top);
mSurfaceLayer = mAnimLayer;
final DisplayContent displayContent = w.getDisplayContent();
if (displayContent != null) {
mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack());
}
mSurfaceControl.setLayer(mAnimLayer);
mSurfaceControl.setAlpha(0);
mSurfaceShown = false;
} catch (RuntimeException e) {
Slog.w(TAG, "Error creating surface in " + w, e);
mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
}
mLastHidden = true;
} finally {
SurfaceControl.closeTransaction();
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
"<<< CLOSE TRANSACTION createSurfaceLocked");
}
我们再来看看SurfaceControl的构造函数,这里主要是调用了nativeCreate函数来获取mNativeObject对象
public SurfaceControl(SurfaceSession session,
String name, int w, int h, int format, int flags)
throws OutOfResourcesException {
......
mName = name;
mNativeObject = nativeCreate(session, name, w, h, format, flags);
if (mNativeObject == 0) {
throw new OutOfResourcesException(
"Couldn't allocate SurfaceControl native object");
}
mCloseGuard.open("release");
}
我们再看nativeCreate函数中,主要就是利用传下来的SurfaceSession对象获取client,然后调用createSurface。最后将创建的Surface对象返回,保存在SurfaceControl的mNativeObject对象中。这里的session就是WindowState的Session对象的SurfaceSession对象,而这个对象就是保存着和SurfaceFlinger通信的client对象。
static jlong nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
jstring nameStr, jint w, jint h, jint format, jint flags) {
ScopedUtfChars name(env, nameStr);
sp client(android_view_SurfaceSession_getClient(env, sessionObj));
sp surface = client->createSurface(
String8(name.c_str()), w, h, format, flags);
if (surface == NULL) {
jniThrowException(env, OutOfResourcesException, NULL);
return 0;
}
surface->incStrong((void *)nativeCreate);
return reinterpret_cast(surface.get());
}
这里创建的SurfaceControl native层是在SurfaceComposerClient中createSurface函数中创建的,这里通过mClient连接SurfaceFlinger获取handle和gbp,然后创建SurfaceControl对象。这个SurfaceControl才是最终在java层的SurfaceControl的nativeObject对象。
sp SurfaceComposerClient::createSurface(
const String8& name,
uint32_t w,
uint32_t h,
PixelFormat format,
uint32_t flags)
{
sp sur;
if (mStatus == NO_ERROR) {
sp handle;
sp gbp;
status_t err = mClient->createSurface(name, w, h, format, flags,
&handle, &gbp);
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
sur = new SurfaceControl(this, handle, gbp);
}
}
return sur;
}
之前博客分析过创建WindowState的过程,会在addWindow中创建WindowState,然后调用其attach函数。WindowState的Session是保存和应用ViewRootImpl通信的Session对象。我们直接来看下WindowState的attach函数。
void attach() {
if (WindowManagerService.localLOGV) Slog.v(
TAG, "Attaching " + this + " token=" + mToken
+ ", list=" + mToken.windows);
mSession.windowAddedLocked();
}
在Session的windowAddedLocked函数中创建了SurfaceSession对象。
void windowAddedLocked() {
if (mSurfaceSession == null) {
if (WindowManagerService.localLOGV) Slog.v(
WindowManagerService.TAG, "First window added to " + this + ", creating SurfaceSession");
mSurfaceSession = new SurfaceSession();
if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(
WindowManagerService.TAG, " NEW SURFACE SESSION " + mSurfaceSession);
mService.mSessions.add(this);
if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
mService.dispatchNewAnimatorScaleLocked(this);
}
}
mNumWindow++;
}
SurfaceSession对象的构造函数就调用了nativeCreate函数,返回值保存在mNativeClient中了。
public SurfaceSession() {
mNativeClient = nativeCreate();
}
这里的nativeCreate是在android_view_SurfaceSession.cpp中的jni函数,这里就是创建了SurfaceComposerClient对象,然后保存在了java层SurfaceSession的mNativeClient中了。
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
SurfaceComposerClient* client = new SurfaceComposerClient();
client->incStrong((void*)nativeCreate);
return reinterpret_cast(client);
}
在SurfaceComposerClient::onFirstRef函数中(就是在对象新建之前会调用这个函数),里面调用了ComposerService的createConnection 并且把返回值存入mClient对象。这个对象就是连接SurfaceFlinger的client对象。
void SurfaceComposerClient::onFirstRef() {
sp sm(ComposerService::getComposerService());
if (sm != 0) {
sp conn = sm->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
而最终ComposerService的connectLocked函数返回是连接SurfaceFlinger进程的client端的binder。
void ComposerService::connectLocked() {
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
assert(mComposerService != NULL);
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComposerService& mComposerService;
virtual void binderDied(const wp& who) {
ALOGW("ComposerService remote (surfaceflinger) died [%p]",
who.unsafe_get());
mComposerService.composerServiceDied();
}
public:
DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
};
mDeathObserver = new DeathObserver(*const_cast(this));
IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}
/*static*/ sp ComposerService::getComposerService() {
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
if (instance.mComposerService == NULL) {
ComposerService::getInstance().connectLocked();
assert(instance.mComposerService != NULL);
ALOGD("ComposerService reconnected");
}
return instance.mComposerService;
}
我们再来回顾WMS中relayout 把Surface传给应用ViewRootImpl,是调用了如下函数。是Surface对象的copyFrom函数
outSurface.copyFrom(surfaceControl);
这里我们调用了native函数nativeCreateFromSurfaceControl重新获取一个一个native对象,最后再调用Surface的setNativeObjectLocked函数保存在Surface对象的mNativeObject中。
public void copyFrom(SurfaceControl other) {
if (other == null) {
throw new IllegalArgumentException("other must not be null");
}
long surfaceControlPtr = other.mNativeObject;
if (surfaceControlPtr == 0) {
throw new NullPointerException(
"SurfaceControl native object is null. Are you using a released SurfaceControl?");
}
long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);//传入的参数是native层的SurfaceControl
synchronized (mLock) {
if (mNativeObject != 0) {
nativeRelease(mNativeObject);
}
setNativeObjectLocked(newNativeObject);
}
}
nativeCreateFromSurfaceControl函数就是从native层的SurfaceControl对象调用getSurface对象,然后返回保存在Surface java对象的mNativeObject中。
static jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz,
jlong surfaceControlNativeObj) {
/*
* This is used by the WindowManagerService just after constructing
* a Surface and is necessary for returning the Surface reference to
* the caller. At this point, we should only have a SurfaceControl.
*/
sp ctrl(reinterpret_cast(surfaceControlNativeObj));
sp surface(ctrl->getSurface());
if (surface != NULL) {
surface->incStrong(&sRefBaseOwner);
}
return reinterpret_cast(surface.get());
}
最终调用了SurfaceControl的getSurface,之前在SurfaceComposerClient中连接SurfaceFlinger时把gbp,传入了SurfaceControl。这里就是创建Surface使用。
sp SurfaceControl::getSurface() const
{
Mutex::Autolock _l(mLock);
if (mSurfaceData == 0) {
// This surface is always consumed by SurfaceFlinger, so the
// producerControlledByApp value doesn't matter; using false.
mSurfaceData = new Surface(mGraphicBufferProducer, false);
}
return mSurfaceData;
}
因此最后就很明显,WMS中有些窗口需要设置属性、大小、Z轴等最后调用的是SurfaceControl.cpp,而应用申请buffer等是调用Surface.cpp。这样就把WMS和ViewRootImpl分开了。
上面说到WMS的窗口设置属性和应用的ViewRootImpl最后是通过SurfaceControl和Surface的native层和SurfaceFlinger通信的。
我们先来看SurfaceControl的,以下面例子为例:
public void setLayer(int zorder) {
checkNotReleased();
nativeSetLayer(mNativeObject, zorder);
}
然后到android_view_SurfaceControl.cpp的nativeSetLayer,最后就是调用保存在SurfaceControl java层的mNativeObjcet(这个就是native层的SurfaceControl)。因此最后是调用了SurfaceControl native的setLayer
static void nativeSetLayer(JNIEnv* env, jclass clazz, jlong nativeObject, jint zorder) {
SurfaceControl* const ctrl = reinterpret_cast(nativeObject);
status_t err = ctrl->setLayer(zorder);
if (err < 0 && err != NO_INIT) {
doThrowIAE(env);
}
}
SurfaceControl中setLayer是调用了SurfaceComposerClient的setLayer函数,在SurfaceComposerClient::setLayer又是调用了Composer的setLayer函数
status_t SurfaceControl::setLayer(uint32_t layer) {
status_t err = validate();
if (err < 0) return err;
return mClient->setLayer(mHandle, layer);
}
status_t SurfaceComposerClient::setLayer(const sp& id, uint32_t z) {
return getComposer().setLayer(this, id, z);
}
这里最后调用Composer的setLayer函数,这里通过getLayerStateLocked获取到对应layer的state。像position,size等都是通过这个函数获取其layer的state,然后再修改其相关值。
status_t Composer::setLayer(const sp& client,
const sp& id, uint32_t z) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
return BAD_INDEX;
s->what |= layer_state_t::eLayerChanged;
s->z = z;
return NO_ERROR;
}
我们来看getLayerStateLocked就是获取相关的ComposerState,Composer把所有的Layer的state都放在mComposerStates中。
layer_state_t* Composer::getLayerStateLocked(
const sp& client, const sp& id) {
ComposerState s;
s.client = client->mClient;
s.state.surface = id;
ssize_t index = mComposerStates.indexOf(s);
if (index < 0) {
// we don't have it, add an initialized layer_state to our list
index = mComposerStates.add(s);//没有这个layer,把它添加到mComposerStates中
}
ComposerState* const out = mComposerStates.editArray();
return &(out[index].state);
}
这里我们不得不提下,整个SurfaceFlinger和SystemServer通信就一个ComposerService,因为它是单例。但是SurfaceControl有很多,每个窗口都有一个。但是最后所有的SurfaceControl都要在这里ComposerService和SurfaceFlinger通信,因此在mComposerStates中保存了所有layer的state。是通过SurfaceControl的openTransaction开启closeTransaction结束。然后一把和SurfaceFlinger通信,避免频繁通信造成效率下降。(具体我们下篇博客分析),但是比如我们createSurface是每个SurfaceComposerClient自己通过mClient和SurfaceFlinger通信,创建一个layer的。
我们再来看SurfaceComposerClient的onFirstRef函数,是调用了SurfaceFlinger的createConnection,然后保存在了自己的mClient中。这个mClient就是每个SurfaceControl用来和SurfaceFlinger通信的。
void SurfaceComposerClient::onFirstRef() {
sp sm(ComposerService::getComposerService());
if (sm != 0) {
sp conn = sm->createConnection();
if (conn != 0) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
我们再来看看SurfaceFlinger的createConnection函数,就是新建了一个Client对象。这个对象是一个Binder的server端。
sp SurfaceFlinger::createConnection()
{
sp bclient;
sp client(new Client(this));
status_t err = client->initCheck();
if (err == NO_ERROR) {
bclient = client;
}
return bclient;
}
这个Client的createSurface就是调用了SurfaceFlinger的createLayer,然后创建一个layer。这个layer主要是一个handle和一个gbp对象。
status_t Client::createSurface(
const String8& name,
uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
sp* handle,
sp* 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* handle;
sp* 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* handle,
sp* 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);
return true;
}
};
sp msg = new MessageCreateLayer(mFlinger.get(),
name, this, w, h, format, flags, handle, gbp);
mFlinger->postMessageSync(msg);
return static_cast( msg.get() )->getResult();
}
这个client对象就是用来创建Surface,销毁Surface,获取和清除Surface信息。
下面我们再来看java层的Surface,看lockCanvas函数。最后是调用了nativeLockCanvas函数
public Canvas lockCanvas(Rect inOutDirty)
throws Surface.OutOfResourcesException, IllegalArgumentException {
synchronized (mLock) {
checkNotReleasedLocked();
if (mLockedObject != 0) {
// Ideally, nativeLockCanvas() would throw in this situation and prevent the
// double-lock, but that won't happen if mNativeObject was updated. We can't
// abandon the old mLockedObject because it might still be in use, so instead
// we just refuse to re-lock the Surface.
throw new IllegalArgumentException("Surface was already locked");
}
mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
return mCanvas;
}
}
我们再来看android_view_Surface.cpp的nativeLockCanvas函数,先是调用Surface的lock函数,这个函数会从SurfaceFlinger中申请buffer,然后
static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
sp surface(reinterpret_cast(nativeObject));
if (!isSurfaceValid(surface)) {
doThrowIAE(env);
return 0;
}
Rect dirtyRect;
Rect* dirtyRectPtr = NULL;
if (dirtyRectObj) {
dirtyRect.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
dirtyRect.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
dirtyRect.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
dirtyRect.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
dirtyRectPtr = &dirtyRect;
}
ANativeWindow_Buffer outBuffer;
status_t err = surface->lock(&outBuffer, dirtyRectPtr);//会从SurfaceFlinger中申请buffer
if (err < 0) {
const char* const exception = (err == NO_MEMORY) ?
OutOfResourcesException :
"java/lang/IllegalArgumentException";
jniThrowException(env, exception, NULL);
return 0;
}
SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
convertPixelFormat(outBuffer.format),
kPremul_SkAlphaType);
if (outBuffer.format == PIXEL_FORMAT_RGBX_8888) {
info.fAlphaType = kOpaque_SkAlphaType;
}
SkBitmap bitmap;
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
bitmap.setInfo(info, bpr);
if (outBuffer.width > 0 && outBuffer.height > 0) {
bitmap.setPixels(outBuffer.bits);
} else {
// be safe with an empty bitmap.
bitmap.setPixels(NULL);
}
Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
nativeCanvas->setBitmap(bitmap);
if (dirtyRectPtr) {
nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top,
dirtyRect.right, dirtyRect.bottom);
}
if (dirtyRectObj) {
env->SetIntField(dirtyRectObj, gRectClassInfo.left, dirtyRect.left);
env->SetIntField(dirtyRectObj, gRectClassInfo.top, dirtyRect.top);
env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right);
env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom);
}
// Create another reference to the surface and return it. This reference
// should be passed to nativeUnlockCanvasAndPost in place of mNativeObject,
// because the latter could be replaced while the surface is locked.
sp lockedSurface(surface);
lockedSurface->incStrong(&sRefBaseOwner);
return (jlong) lockedSurface.get();
}
在Surface的lock函数中会调用dequeueBuffer函数,这个函数会通过mGraphicBufferProducer的dequeueBuffer函数来申请buffer
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
ATRACE_CALL();
ALOGV("Surface::dequeueBuffer");
uint32_t reqWidth;
uint32_t reqHeight;
bool swapIntervalZero;
PixelFormat reqFormat;
uint32_t reqUsage;
{
Mutex::Autolock lock(mMutex);
reqWidth = mReqWidth ? mReqWidth : mUserWidth;
reqHeight = mReqHeight ? mReqHeight : mUserHeight;
swapIntervalZero = mSwapIntervalZero;
reqFormat = mReqFormat;
reqUsage = mReqUsage;
} // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer
int buf = -1;
sp fence;
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,
reqWidth, reqHeight, reqFormat, reqUsage);
if (result < 0) {
ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d, %d)"
"failed: %d", swapIntervalZero, reqWidth, reqHeight, reqFormat,
reqUsage, result);
return result;
}
Mutex::Autolock lock(mMutex);
sp& gbuf(mSlots[buf].buffer);
// this should never happen
ALOGE_IF(fence == NULL, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
freeAllBuffers();
}
if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
if (result != NO_ERROR) {
ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result);
mGraphicBufferProducer->cancelBuffer(buf, fence);
return result;
}
}
if (fence->isValid()) {
*fenceFd = fence->dup();
if (*fenceFd == -1) {
ALOGE("dequeueBuffer: error duping fence: %d", errno);
// dup() should never fail; something is badly wrong. Soldier on
// and hope for the best; the worst that should happen is some
// visible corruption that lasts until the next frame.
}
} else {
*fenceFd = -1;
}
*buffer = gbuf.get();
return OK;
}
这样我们很明显,应用申请buffer和窗口设置属性等完全分开来了。应用ViewRootImpl申请buffer通过Surface、窗口在WMS中通过SurfaceControl设置属性、Z轴、大小(通过openTransaction和closeTransaction开启关闭,因为设置窗口属性是所有窗口一起设置,然后通过ComposerService和SurfaceFlinger连接一起设置过去)。而在创建SurfaceComposerClient时,会和SurfaceFlinger通信调用一个createConnection函数,然后SurfaceFlinger那边会创建一个Client对象(Binder的server端),这样每个SurfaceComposerClient都有一个client和SurfaceFlinger通信了(也就是在SurfaceControl中能通过这个client,申请SurfaceFlinger创建一个layer,这种行为是每个SurfaceControl自己和SurfaceFlinger通信,而不是一起通过ComposerService一起喝SurfaceFlinger通信了)。