一、SurfaceControl的創建
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<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
- sp<SurfaceControl> 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<jlong>(surface.get());
- }
這裏創建的SurfaceControl native層是在SurfaceComposerClient中createSurface函數中創建的,這裏通過mClient連接SurfaceFlinger獲取handle和gbp,然後創建SurfaceControl對象。這個SurfaceControl纔是最終在java層的SurfaceControl的nativeObject對象。
- sp<SurfaceControl> SurfaceComposerClient::createSurface(
- const String8& name,
- uint32_t w,
- uint32_t h,
- PixelFormat format,
- uint32_t flags)
- {
- sp<SurfaceControl> sur;
- if (mStatus == NO_ERROR) {
- sp<IBinder> handle;
- sp<IGraphicBufferProducer> 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<jlong>(client);
- }
在SurfaceComposerClient::onFirstRef函數中(就是在對象新建之前會調用這個函數),裏面調用了ComposerService的createConnection 並且把返回值存入mClient對象。這個對象就是連接SurfaceFlinger的client對象。
- void SurfaceComposerClient::onFirstRef() {
- sp<ISurfaceComposer> sm(ComposerService::getComposerService());
- if (sm != 0) {
- sp<ISurfaceComposerClient> 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<IBinder>& who) {
- ALOGW("ComposerService remote (surfaceflinger) died [%p]",
- who.unsafe_get());
- mComposerService.composerServiceDied();
- }
- public:
- DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
- };
-
- mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
- IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
- }
-
- /*static*/ sp<ISurfaceComposer> 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<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
- sp<Surface> surface(ctrl->getSurface());
- if (surface != NULL) {
- surface->incStrong(&sRefBaseOwner);
- }
- return reinterpret_cast<jlong>(surface.get());
- }
最終調用了SurfaceControl的getSurface,之前在SurfaceComposerClient中連接SurfaceFlinger時把gbp,傳入了SurfaceControl。這裏就是創建Surface使用。
- sp<Surface> 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分開了。
二、Surface和SurfaceControl的native層
上面說到WMS的窗口設置屬性和應用的ViewRootImpl最後是通過SurfaceControl和Surface的native層和SurfaceFlinger通信的。
2.1 SurfaceControl
我們先來看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<SurfaceControl *>(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<IBinder>& 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<SurfaceComposerClient>& client,
- const sp<IBinder>& 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<SurfaceComposerClient>& client, const sp<IBinder>& 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<ISurfaceComposer> sm(ComposerService::getComposerService());
- if (sm != 0) {
- sp<ISurfaceComposerClient> conn = sm->createConnection();
- if (conn != 0) {
- mClient = conn;
- mStatus = NO_ERROR;
- }
- }
- }
我們再來看看SurfaceFlinger的createConnection函數,就是新建了一個Client對象。這個對象是一個Binder的server端。
- sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
- {
- sp<ISurfaceComposerClient> bclient;
- sp<Client> 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<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);
- 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();
- }
這個client對象就是用來創建Surface,銷燬Surface,獲取和清除Surface信息。
2.2 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> surface(reinterpret_cast<Surface *>(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<Surface> 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> 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<GraphicBuffer>& 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通信了)。