Android6.0 显示系统(一) Surface创建

原创 2016年09月27日 10:58:59

之前在分析Activity的时候,我们分析过Surface创建。这个系列的博客是讲述显示系统,这里再系统的分析下Surface创建过程。

之前我们分析在Activity在调用attach方法时,建立ViewRootImpl,以及创建其Surface过程,还有在WMS中创建Surface的过程。

这篇博客我们通过另外一个方式分析,但是其实质是一样的。


一、应用层创建Surface

应用开发中很少直接使用Surface,因为每个Activity中已经创建好了各自的Surface对象(就是之前博客分析的在ViewRootImpl通过WMS创建的),通常只有一些特殊应用才需要在Activity之外创建Surface,例如照相机、视频播放应用。通常这些应用也是通过创建SurfaceView来使用Surface。在应用中不直接创建一个可用的Surface对象,或者说直接创建出来的Surface对象也没用,因为这样的Surface不能和SurfaceFlinger之间有关联。

下面我们就来看下SurfaceView是如何创建Surface的,在SurfaceView有两个Surface一个mSurface表示正在用的,另一个mNewSurface代表我们要切换的。

    final Surface mSurface = new Surface();       // Current surface in use
    final Surface mNewSurface = new Surface();    // New surface we are switching to

至于Surface的构造函数没什么代码,我们就不看了。

我们再来看SurfaceView的updateWindow函数,也是调用了WindowSession的relayout函数,和之前Activity创建Surface的流程一样,这里获取到mNewSurface,再把mNewSurface的数据复制到mSurface中。

    protected void updateWindow(boolean force, boolean redrawNeeded) {
        ......
        relayoutResult = mSession.relayout(mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
        visible ? VISIBLE : GONE,
        WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
        mWinFrame, mOverscanInsets, mContentInsets,
        mVisibleInsets, mStableInsets, mOutsets, mConfiguration,
        mNewSurface);
        ......
        mSurface.transferFrom(mNewSurface);
        ......
    }

mSession对象是IWindowSession,它是WMS中Session的代理对象。下面这是IWindowSession.aidl文件中relayout函数的定义,我们可以看到outSurface的参数前面有一个out代表这是一个返回参数,从WMS获取这个对象的。而返回数据都是通过Parcel来传递的。那下面我们来看看Surface的readFromParcel函数。

    int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
            int requestedWidth, int requestedHeight, int viewVisibility,
            int flags, out Rect outFrame, out Rect outOverscanInsets,
            out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets,
            out Rect outOutsets, out Configuration outConfig, out Surface outSurface);

我们来看下Surface的readFromParcel函数,前面是参数检查,后面先是调用了nativeReadFromParcel函数来重新创建一个native层的Surface,然后调用setNativeObjectLocked来保存这个native层的Surface到mNativeObject对象

    public void readFromParcel(Parcel source) {
        if (source == null) {
            throw new IllegalArgumentException("source must not be null");
        }

        synchronized (mLock) {
            // nativeReadFromParcel() will either return mNativeObject, or
            // create a new native Surface and return it after reducing
            // the reference count on mNativeObject.  Either way, it is
            // not necessary to call nativeRelease() here.
            mName = source.readString();
            setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
        }
    }

我们来看JNI层的nativeReadFromParcel函数,这个函数在android_view_Surface.cpp中,会将Parcel对象中读取一个Binder对象,并且用它创建一个c层的Surface,并且返回。这里我们还不清楚这个Binder是什么。

static jlong nativeReadFromParcel(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject parcelObj) {
    Parcel* parcel = parcelForJavaObject(env, parcelObj);//将数据解析成parcel
    if (parcel == NULL) {
        doThrowNPE(env);
        return 0;
    }

    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 //和原来的相同
            && (IInterface::asBinder(self->getIGraphicBufferProducer()) == binder)) {
        // same IGraphicBufferProducer, return ourselves
        return jlong(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);//创建一个Surface
        // 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 jlong(sur.get());
}

我们来看Surface,我们把binder对象保存在mGraphicBufferProducer中了。

Surface::Surface(
        const sp<IGraphicBufferProducer>& bufferProducer,
        bool controlledByApp)
    : mGraphicBufferProducer(bufferProducer),
      mGenerationNumber(0)



二、WMS中Surface的创建过程

用户进程中调用Session类的relayout接口来获取WMS创建的Surface。而Session类的relayout接口实际上后面调用了WMS的relayout的relayoutWindow方法。

我们来看下WMS的relayoutWindow函数,显示调用了winAnimator的createSurfaceLocked方法得到一个SurfaceControl对象,并使用它作为参数调整Surface类的copyFrom方法。

    public int relayoutWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int requestedWidth,
            int requestedHeight, int viewVisibility, int flags,
            Rect outFrame, Rect outOverscanInsets, Rect outContentInsets,
            Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Configuration outConfig,
            Surface outSurface) {
            ......
            SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
                    if (surfaceControl != null) {
                        outSurface.copyFrom(surfaceControl);
                    }
            ......

我们先来看Surface的copyFrom方法,这个方法其实很简单只是把SurfaceControl的native层的SurfaceControl的Surface复制到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);

        synchronized (mLock) {
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
            }
            setNativeObjectLocked(newNativeObject);
        }
    }

nativeCreateFromSurfaceControl方法是把native层的SurfaceControl的surface传出去。

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());//获取Surface
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner);
    }
    return reinterpret_cast<jlong>(surface.get());//这个get方法是强指针的方法,获取其指针而已
}

再来看看SurfaceControl的getSurface方法。

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;
}


2.1 SurfaceControl的创建

下面我们再来看看SurfaceControl的创建,下面SurfaceTrace是SurfaceControl的一个子类。

    SurfaceControl createSurfaceLocked() {
        ......
        mSurfaceControl = new SurfaceTrace(
        mSession.mSurfaceSession,
        attrs.getTitle().toString(),
        width, height, format, flags);
        ......

我们先看下SurfaceTrace的构造函数,先调用了父类的构造函数

        public SurfaceTrace(SurfaceSession s,
                       String name, int w, int h, int format, int flags)
                   throws OutOfResourcesException {
            super(s, name, w, h, format, flags);
            mName = name != null ? name : "Not named";
            mSize.set(w, h);
            synchronized (sSurfaces) {
                sSurfaces.add(0, this);
            }
        }

我们再来看SurfaceControl的构造函数,就是调用了nativeCreate来新建一个mNativeObject对象。前面我们看过通过这个对象就可以获取native层的Surface。

    public SurfaceControl(SurfaceSession session,
            String name, int w, int h, int format, int flags)
                    throws OutOfResourcesException {
        if (session == null) {
            throw new IllegalArgumentException("session must not be null");
        }
        if (name == null) {
            throw new IllegalArgumentException("name must not be null");
        }

        if ((flags & SurfaceControl.HIDDEN) == 0) {
            Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set "
                    + "to ensure that they are not made visible prematurely before "
                    + "all of the surface's properties have been configured.  "
                    + "Set the other properties and make the surface visible within "
                    + "a transaction.  New surface name: " + name,
                    new Throwable());
        }

        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");
    }

我们来看SurfaceControl的nativeCreate的JNI对应的方法,先用SurfaceSession获取SurfaceComposerClient,然后调用createSurface方法,获取SurfaceControl。

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());
}

我们来看android_view_SurfaceSession_getClient就是获取SurfaceSession的mNativeObject对象,也就是SurfaceComposerClient对象。

sp<SurfaceComposerClient> android_view_SurfaceSession_getClient(
        JNIEnv* env, jobject surfaceSessionObj) {
    return reinterpret_cast<SurfaceComposerClient*>(
            env->GetLongField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient));
}


2.2  SurfaceSession创建

那么Session的成员变量mSurfaceSession又是什么时候创建的?

之前在分析ViewRootImpl的setView时候,会调用Session的addToDisplay函数,在这个函数调用了PKMS的addWindow函数,而在addWindow方法,后面会创建一个WindowState对象,然后调用了其attach方法。

            ......
            WindowState win = new WindowState(this, session, client, token,
                    attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
            ......
            win.attach();

我们来看下这个WindowState的attach方法,调用了Session的windowAddedLocked方法。

    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 JNI函数。

    public SurfaceSession() {
        mNativeClient = nativeCreate();
    }

我们来看下这个JNI函数,创建了一个SurfaceComposerClient对象

static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    SurfaceComposerClient* client = new SurfaceComposerClient();
    client->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(client);
}


2.3 SurfaceComposerClient连接SurfaceFlinger

SurfaceComposerClient对象的构造函数也没有什么,因为SurfaceComposerClient类也是RefBase类派生的,所以我们来看下onFirstRef函数。

SurfaceComposerClient::SurfaceComposerClient()
    : mStatus(NO_INIT), mComposer(Composer::getInstance())
{
}

void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sm(ComposerService::getComposerService());
    if (sm != 0) {
        sp<ISurfaceComposerClient> conn = sm->createConnection();
        if (conn != 0) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

onFirstRef函数先调用了ComposerService的getComposerService方法来获取一个ISurfaceComposer的指针,然后调用它的createConnection来得到一个ISurfaceComposerClient的指针,并且保存在mClient成员变量中。

最后我们知道在SurfaceControl中是调用SurfaceComposerClient的createSurface来得到Surface对象的。

我们再来看ComposerService::getComposerService函数,调用了connectLocked函数

/*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;
}

connectLocked函数只是获取SurfaceFlinger的Binder对象,然后保存在mComposerService。

void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    ......

所以最后在SurfaceComposerClient的onFirstRef函数中,先是获取SurfaceFlinger的Binder对象,然后调用函数createConnection函数,最终也是到SurfaceFlinger的createConnection函数。我们来看SurfaceFlinger的createConnection函数,创建一个client对象(这也是一个Binder服务),最后返回这个对象。而返回的对象保存在SurfaceComposerClient类的mClient成员变量中。这样每一个连接都会有一个新的Client对象。

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;
}


最后在SurfaceComposerClient中创建Surface,也是调用了mClient的createSurface,就到SurfaceFlinger的Client对象的createSurface函数了,获取了handle和gbp对象就创建了SurfaceControl对象。

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;
}

我们再来看SurfaceControl对象的构造函数就是初始化各种变量。

SurfaceControl::SurfaceControl(
        const sp<SurfaceComposerClient>& client,
        const sp<IBinder>& handle,
        const sp<IGraphicBufferProducer>& gbp)
    : mClient(client), mHandle(handle), mGraphicBufferProducer(gbp)
{
}
最后通过getSurface来新建一个Surface对象,Surface对象一个重要的参数是mGraphicBufferProducer,而这个对象的一个参数就是gbp
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;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

Android图形系统之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的联系

/********************************************************************************************  * aut...
  • conowen
  • conowen
  • 2012年08月03日 17:29
  • 51097

android的Surface详解

JAVA层次的Surface系统1.       过程描述android.view.Surfaceview类继承自android.view.View类,在view层次关系上提供精细绘制Surface的...

android6.0 Activity(四) Surface创建

原文:http://blog.csdn.net/luoshengyang/article/details/8303098,原文代码比较老了,但是核心不变。在原文基础上修改了一些代码,以及加入自己少量的...

Android深入浅出之Surface[1]

Android深入浅出之Surface一目的本节的目的就是为了讲清楚Android中的Surface系统,大家耳熟能详的SurfaceFlinger到底是个什么东西,它的工作流程又是怎样的。当然,鉴于...
  • Innost
  • Innost
  • 2011年02月05日 15:30
  • 53498

Android6.0 显示系统(六) 图像的输出过程

上篇博客分析到SurfaceFlinger收到了VSync信号后,调用了handleMessageRefresh函数,这篇博客主要就是分析这个函数,我们先看看它的代码: void SurfaceFli...

Android6.0 显示系统(五) SurfaceFlinger服务

SurfaceFlinger是一个独立的进程,我们来看下init.rc关于SurfaceFlinger的代码,我们可以看到SurfaceFlinger是属于core服务的。 service surfa...

Android6.0 显示系统(二) SurfaceFlinger创建Surface

接上篇博客分析到SurfaceComposerClient中调用createSurface函数会最后调用到SurfaceFlinger的Client的createSurface函数。 我们来看下这个函...

Android应用程序创建Surface过程源码分析

在上一篇 Android远程代理对象BpSurface的获取过程源码分析文章中,介绍了应用程序在SurfaceFlinger服务端创建对应的Layer对象过程,同时返回BpSurface远程代理对象...

android之surfaceView详解--自定义surfaceView和用于视频surfaceview

android之surfaceView详解--自定义surfaceView和用于视频surfaceview,mediaPlayer详解
  • zhongwn
  • zhongwn
  • 2016年07月13日 17:02
  • 8522

android surfaceView 的简单使用 画图,拖动效果

前面说到了画图,其实更好的就是使用 surfaceView了。 surfaceView 继承于 View ,View里面嵌套了一个专门用于画图的 surface, 对于一个View的onDraw()...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android6.0 显示系统(一) Surface创建
举报原因:
原因补充:

(最多只允许输入30个字)