Android6.0 SurfaceControl分析(一)SurfaceControl创建&使用 Surface创建&使用

来源:互联网 发布:办公自动化软件 编辑:程序博客网 时间:2024/04/30 06:35

一、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通信了)。








1 0
原创粉丝点击