Android4.4 Surface从java到native的创建过程

研究Surface的创建流程需要一个精简的流程,不然跳转太多,脑子都乱了。先讲一个大致的过程:ViewRootImpl在构造时会new一个Surface,在relayoutWindow方法中传入mSurface,这个跨进程的调用会在binderserver端新构造一个Surface,在WMS中构造SurfaceControl,然后将生成的SurfaceControl传入binderserver端的Surface,最后把这个binderserver端的Surface返回到调用进程,即ViewRootImpl中。下面是调用关键方法:

1.ViewRootImpl的relayoutWindow方法中调用Session的relayout方法来设置mSurface
 private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
......
        int relayoutResult = mWindowSession.relayout(
                mWindow, mSeq, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f),
                viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
                mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                mPendingConfiguration, mSurface);
......
        return relayoutResult;
    }

调用mWindowSession的relayout方法,注意这是个binder调用。

2.onTranct中返回一个新构造的Surface

case TRANSACTION_relayout:
{
......
android.view.Surface _arg12;
_arg12 = new android.view.Surface();//构造一个新的Surface
int _result = this.relayout(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6, _arg7, _arg8, _arg9, _arg10, _arg11, _arg12);
......
if ((_arg12!=null)) {
reply.writeInt(1);
_arg12.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
return true;
}

3.在Session调用WMS的relayout方法

    public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewFlags,
            int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
            Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
        int res = mService.relayoutWindow(this, window, seq, attrs,
                requestedWidth, requestedHeight, viewFlags, flags,
                outFrame, outOverscanInsets, outContentInsets, outVisibleInsets,
                outConfig, outSurface);
        return res;
    }

4.WMS的relayout方法中构造SurfaceControl,并用这个SurfaceControl构造传入的Surface

SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();//创建SurfaceControl
                    if (surfaceControl != null) {
                        outSurface.copyFrom(surfaceControl);//通过SurfaceControl设置Surface
                        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();
                    }
5.winAnimator的createSurfaceLocked方法中生成SurfaceControl 
  mSurfaceControl = new SurfaceControl(
                        mSession.mSurfaceSession,
                        attrs.getTitle().toString(),
                        w, h, format, flags);
6.将生成的Surface传回ViewRootImpl
public int relayout(android.view.IWindow window, int seq, android.view.WindowManager.LayoutParams attrs, int requestedWidth, int requestedHeight, int viewVisibility, int flags, android.graphics.Rect outFrame, android.graphics.Rect outOverscanInsets, android.graphics.Rect outContentInsets, android.graphics.Rect outVisibleInsets, android.content.res.Configuration outConfig, android.view.Surface outSurface) throws android.os.RemoteException
{
try {
......
mRemote.transact(Stub.TRANSACTION_relayout, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
if ((0!=_reply.readInt())) {
outFrame.readFromParcel(_reply);//从返回结果中读取参数,填充传入的Surface
}
return _result;}
流程是这样,主要分析点:
1.binder调用后返回值是如何设置Surface的,即解析readFromParcel
2.WMS中根据生成的SurfaceControl构造Surface,即分析outSurface.copyFrom(surfaceControl);
3.SurfaceControl的生成,即分析其构造方法

4.Surface的binder传递,即分析_arg12.writeToParcel


先啃硬骨头:

一  :SurfaceControl的生成

在WindowStateAnimator的createSurfaceLocked方法中构造SurfaceControl,方法如下:

 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);
        mCloseGuard.open("release");
    }

进入native方法:

static jint 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);
    surface->incStrong((void *)nativeCreate);
    return int(surface.get());
}
首先根据传入的SurfaceSession找到其mNativeClient,即SurfaceComposerClient;然后调用SurfaceComposerClient的createSurface方法创建一个native的SurfaceControl,并返回到java层的mNativeObject中。可以看出java的SurfaceControl就是native层的SurfaceControl的封装。

1.1 SurfaceControl的生成:SurfaceComposerClient的createSurface方法

sp<SurfaceControl> SurfaceComposerClient::createSurface(
        const String8& name,
        uint32_t w,
        uint32_t h,
        PixelFormat format,
        uint32_t flags)
{
    sp<SurfaceControl> sur;
        sp<IBinder> handle;
        sp<IGraphicBufferProducer> gbp;//注意此处的gbp传入的是地址
        status_t err = mClient->createSurface(name, w, h, format, flags,
                &handle, &gbp);

        if (err == NO_ERROR) {
            sur = new SurfaceControl(this, handle, gbp);//构造新的SurfaceControl,追踪构造参数handle和gbp
        }
    return sur;
}
mClient类型是ISurfaceComposerClient,SurfaceComposerClient在onFirstRef方法中,调用SurfaceFlinger的createConnection方法获取的。进入Bp端看看传入参数:
//ISurfaceComposerClient.cpp

    virtual status_t createSurface(const String8& name, uint32_t w,
            uint32_t h, PixelFormat format, uint32_t flags,
            sp<IBinder>* handle,
            sp<IGraphicBufferProducer>* gbp) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
        data.writeString8(name);
        data.writeInt32(w);
        data.writeInt32(h);
        data.writeInt32(format);
        data.writeInt32(flags);
		//注意:并未传入gbp,而是从binder调用的返回值中强制将返回的IGraphicBufferProducer赋值给gbp;同理handle也是这样处理的,因此要注意在bn端是写入的哪个对象
        remote()->transact(CREATE_SURFACE, data, &reply);
        *handle = reply.readStrongBinder();
        *gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
        return reply.readInt32();
    }
进入Bn端看看接收的参数:
    status_t BnSurfaceComposerClient::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
     switch(code) {
        case CREATE_SURFACE: {
            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
......
            sp<IBinder> handle;
            sp<IGraphicBufferProducer> gbp;
            status_t result = createSurface(name, w, h, format, flags,
                    &handle, &gbp);
			//注意,在这里写入的handle和gbp,他们是可以进程间传递的
            reply->writeStrongBinder(handle);
            reply->writeStrongBinder(gbp->asBinder());//可知bp端读取的就是这个gbp
            reply->writeInt32(result);
            return NO_ERROR;
        } break;
	}
}
进入Client的createSurface方法:

status_t Client::createSurface(
        const String8& name,
        uint32_t w, uint32_t h, PixelFormat format, uint32_t flags,
        sp<IBinder>* handle,
        sp<IGraphicBufferProducer>* gbp)
{

    class MessageCreateLayer : public MessageBase {
        SurfaceFlinger* flinger;
        Client* client;
.....
        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;
        }
    };//创建内部类MessageCreateLayer
	//这里才是createlayer方法的真正内容,将SurfaceFlinger传入,然后向其发消息
    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();
}
直接进入SurfaceFlinger的createLayer方法
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)
{
    status_t result = NO_ERROR;
    sp<Layer> layer;

    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createNormalLayer(client,
                    name, w, h, flags, format,
                    handle, gbp, &layer);//注意,这里又添加了一个layer参数,也是传递地址,看看是如何赋值的
            break;
    }

    if (result == NO_ERROR) {
        addClientLayer(client, *handle, *gbp, layer);
        setTransactionFlags(eTransactionNeeded);
    }
    return result;
}
status_t SurfaceFlinger::createNormalLayer(const sp<Client>& client,
        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
    *outLayer = new Layer(this, client, name, w, h, flags);//新建Layer
    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
    if (err == NO_ERROR) {
    //构造SurfaceControl的两大元素handle和gbp都是在Layer中的,要理解layer
        *handle = (*outLayer)->getHandle();
        *gbp = (*outLayer)->getBufferQueue();
    }
    return err;
}
进入Layer的onFirstRef方法:
void Layer::onFirstRef() {
    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    mBufferQueue = new SurfaceTextureLayer(mFlinger);//getBufferQueue
    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
    mSurfaceFlingerConsumer->setName(mName);
    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
}
追踪handle和gbp的获取:
sp<IBinder> Layer::getHandle() {
    Mutex::Autolock _l(mLock);
    mHasSurface = true;
    class Handle : public BBinder, public LayerCleaner {
        wp<const Layer> mOwner;
    public:
        Handle(const sp<SurfaceFlinger>& flinger, const sp<Layer>& layer)
            : LayerCleaner(flinger, layer), mOwner(layer) {
        }
    };
    return new Handle(mFlinger, this);
}

sp<IGraphicBufferProducer> Layer::getBufferQueue() const {
    return mBufferQueue;
}
可知handle是一个跨进程的类,其中包含所属的layer;gbp就是构造的mBufferQueue。至此可以看到handle和gbp的真实内容,回到构造native层SurfaceControl的方法中:
SurfaceControl::SurfaceControl(
        const sp<SurfaceComposerClient>& client,
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbp)
    : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
{
}
就是保存下参数。至此,SurfaceControl创建结束,native层的创建完,java的就ok了。接下来就是如何将创建的SurfaceControl传到ViewRootImpl的mSurface了。进入:

二:WMS中根据生成的SurfaceControl构造Surface,即分析outSurface.copyFrom(surfaceControl);

    public void copyFrom(SurfaceControl other) {
        int surfaceControlPtr = other.mNativeObject;
        if (surfaceControlPtr == 0) {
            throw new NullPointerException(
                    "SurfaceControl native object is null. Are you using a released SurfaceControl?");
        }
        int newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);

        synchronized (mLock) {
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
            }
            setNativeObjectLocked(newNativeObject);//将获取的surface地址保存到mNativeObject中
        }
    }

将传入的java层的SurfaceControl中的mNativeObject取出,其实这个参数就是native层的SurfaceControl

    static jint nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz,
        jint 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<jint>(surface.get());
}
其实就是使用native层的SurfaceControl的getSurface方法获取一个surface,然后将这个获取的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;
}
在底层的SurfaceControl中new一个Surface。
小结:copyfrom方法主要是通过java层的SurfaceControl封装的SurfaceControl构造一个native层的Surface,然后将这个native层的Surface设置到java层的Surface中。所以SurfaceControl负责构造Surface。

现在WMS端已经构造了一个Surface了,接下来就是将这个Surface传递到远程调用端了。

三:远程传递的过程

1.ontrant端

//Surface的binder传递,即分析_arg12.writeToParcel
    public void writeToParcel(Parcel dest, int flags) {
        if (dest == null) {
            throw new IllegalArgumentException("dest must not be null");
        }
        synchronized (mLock) {
            dest.writeString(mName);
            nativeWriteToParcel(mNativeObject, dest);
        }
        if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
            release();
        }
    }
    
    static void nativeWriteToParcel(JNIEnv* env, jclass clazz,
        jint nativeObject, jobject parcelObj) {
    Parcel* parcel = parcelForJavaObject(env, parcelObj);
    if (parcel == NULL) {
        doThrowNPE(env);
        return;
    }
    sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
    parcel->writeStrongBinder( self != 0 ? self->getIGraphicBufferProducer()->asBinder() : NULL);
}
还是native层的事,其实就是把gbp传过去了
2.看看接收端返回值是如何设置Surface的,即解析readFromParcel
static jint nativeReadFromParcel(JNIEnv* env, jclass clazz,
        jint nativeObject, jobject parcelObj) {
    Parcel* parcel = parcelForJavaObject(env, parcelObj);

    sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
    sp<IBinder> binder(parcel->readStrongBinder());

    // update the Surface only if the underlying IGraphicBufferProducer
    // has changed.
    if (self != NULL
            && (self->getIGraphicBufferProducer()->asBinder() == binder)) {
        // same IGraphicBufferProducer, return ourselves
        return int(self.get());
    }

    sp<Surface> sur;
    sp<IGraphicBufferProducer> gbp(interface_cast<IGraphicBufferProducer>(binder));
    if (gbp != NULL) {
        // we have a new IGraphicBufferProducer, create a new Surface for it
        sur = new Surface(gbp, true);
        // and keep a reference before passing to java
        sur->incStrong(&sRefBaseOwner);
    }

    if (self != NULL) {
        // and loose the java reference to ourselves
        self->decStrong(&sRefBaseOwner);
    }

    return int(sur.get());
}
可知,在ViewRootImpl端的Surface有了native层的Surface。这个Surface和WMS端的Surface有相同的GBP,也就是说ViewRootImpl可以获取内存了。那什么时候使用内存呢?肯定是view要显示出来的时候,这个在下一节分享。





































猜你喜欢

转载自blog.csdn.net/ywlyg/article/details/80006339