从源码角度看surface的创建流程

本文详细探讨了Android系统中Surface在创建过程中涉及的native代码,从WindowManagerService.java的relayoutWindow方法开始,逐步解析SurfaceControl、SurfaceSession到SurfaceFlinger的连接过程,阐述了Surface如何通过Client和Layer进行管理与通信。
摘要由CSDN通过智能技术生成

本篇文章主要想介绍surface在创建过程中,所涉及到的native部分的代码,本篇以及上一篇介绍View的启动的源码都是基于android 7.0的源码进行解析的。

android sdk中的源码只是java部分的,阅读c++的代码可以在这个网站上进行查阅。

前言讲到这里,我们开始进入正题:

我们在之前已经了解了view在framework层中java方法的调用流程,现在接着WindowManagerService.java中的relayoutWindow方法看起

WindowManagerService.java

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, Rect outBackdropFrame,
            Configuration outConfig, Surface outSurface) {
        ···
        synchronized(mWindowMap) {
            WindowState win = windowForClientLocked(session, client, false);
            if (win == null) {
                return 0;
            }

            WindowStateAnimator winAnimator = win.mWinAnimator;
            if (viewVisibility != View.GONE) {
                win.setRequestedSize(requestedWidth, requestedHeight);//设置系统请求所要设置的高度和宽度
            }

           ···


            if (viewVisibility == View.VISIBLE &&
                    (win.mAppToken == null || !win.mAppToken.clientHidden)) {
              ···
                try {
                    result = createSurfaceControl(outSurface, result, win, winAnimator);//当窗口可见时为其创建一个Surface绘图表面
                } catch (Exception e) {
                  ···
                }
                ···
            } else {
               ···
            }

        ···
        return result;
    }

这里的createSurfaceControl()是为ViewRootImpl创建一个SurfaceControl对象,SurfaceControl这个类起到了连接java层与native层的作用,在native层创建Surface对象返回java层进行显示画面。先来看下SufaceControl这个对象的构造方法:

SurfaceControl.java

private static native long nativeCreate(SurfaceSession session, String name,
            int w, int h, int format, int flags)
            throws OutOfResourcesException;

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);//这里调用了native层的一个方法来构造这个对象,我们接着去c++代码中看一下这个方法是用来干什么的
        ···
    }

首先在这里先简单说一下jni方法的命名规则。jni方法命名为一个类的类名加上这个方法的方法名,将其中的‘.’替换为‘_’

/frameworks/base/core/jni/android_view_SurfaceControl.cpp

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));//TAG1
    sp<SurfaceControl> surface = client->createSurface(
            String8(name.c_str()), w, h, format, flags);//TAG2
    if (surface == NULL) {
       jniThrowException(env, OutOfResourcesException, NULL);
        return 0;
   }
    surface->incStrong((void *)nativeCreate);
}

这里通过由上层传下来的SurfaceSession获取SurfaceComposerClient对象,咱们来看一下SurfaceSession是在哪里创建的。

ViewRootImpl.java

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
        synchronized (this) {
            if (mView == null) {
                mView = view;

               ···
                requestLayout();//这里是在另外一个线程中进行设置用于展示界面的窗口,与具体画面的绘制
                if ((mWindowAttributes.inputFeatures
                        & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) {
                    mInputChannel = new InputChannel();
                }
                mForceDecorViewVisibility = (mWindowAttributes.privateFlags
                        & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0;
                try {
                    mOrigWindowType = mWindowAttributes.type;
                    mAttachInfo.mRecomputeGlobalAttributes = true;
                    collectViewAttributes();
                    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(),
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mInputChannel);//这里与requestLayout()中的内容代码其实是并行执行的,在这个语句中主要用来创建与surfaceflinger会话。
                } catch (RemoteException e) {
                    mAdded = false;
                    mView = null;
                    mAttachInfo.mRootView = null;
                    mInputChannel = null;
                    mFallbackEventHandler.setView(null);
                    unscheduleTraversals();
                    setAccessibilityFocus(null, null);
                    throw new RuntimeException("Adding window failed", e);
                } finally {
                    if (restore) {
                        attrs.restore();
                    }
                }

               ···
            }
        }
    }

Session.java

public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets,
            Rect outOutsets, InputChannel outInputChannel) {
        return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
                outContentInsets, outStableInsets, outOutsets, outInputChannel);
    }

WindowManagerService.java

public int addWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
            InputChannel outInputChannel) {
        ···
        synchronized(mWindowMap) {
            ···
            WindowState win = new WindowState(this, session, client, token,
                    attachedWindow, appOp[0], seq, attrs, viewVisibility, displayContent);
            ···
            win.attach();
            ···
        return res;
    }

在这一步中,将ViewRootImpl中的Session对象封装到一个WindowState对象中,在 requestLayout()函数内部会调用到这个对象,用来在native层构建一个SurfaceControl对象。

WindowState.java

void attach() {
        if (WindowManagerService.localLOGV) Slog.v(
            TAG, "Attaching " + this + " token=" + mToken
            + ", list=" + mToken.windows);
        mSession.windowAddedLocked();/
    }

这里的mSession对象就是ViewRootImpl里面的Session对象,这里调用的这个方法创建了一个SurfaceSession对象,用来native层的连接SurfaceFlinger

SufaceSession.java

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

/frameworks/base/core/jni/android_view_SurfaceSession.cpp

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

在native层中创建SurfaceSession其实创建的是一个SurfaceComposerClient对象,咱们在反过头来看TAG1,第一步所调用的sp client(android_view_SurfaceSession_getClient(env, sessionObj));

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

这个函数就是通过SurfaceSession返回一个SurfaceComposerClient对象,在SurfaceComposerClient的构造函数中他连接了native层中的SurfaceFlinger


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

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

ComposerService::ComposerService()
: Singleton<ComposerService>() {
    Mutex::Autolock _l(mLock);
    connectLocked();
}


void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
   }
   ```
    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
    IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}

由于SurfaceFlinger是一个独立的进程,所以connectLocked执行的时候就是通过binder将SurfaceComposerClient与SurfaceFlinger两个类联系起来。我们接着来看TAG3,既然我们已经知道sm是一个对于SurfaceFlinger的一个binder对象,那么他所调用的就是SurfaceFlinger得createConnection()方法。

xref: /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

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!因为一个android系统可能存在多个app来请求SurfaceFlinger的业务,而一个app又可能存在多个surface,而这些surface对象如果分散起来其实是不好管理的,所以android系统为他们构建了一个Client类来负责与SurfaceFlinger来交互,并用来管理自身的Surface对象。那我们回过头来看这个TAG2这部分,他是用Client来创建Surface的

xref: /frameworks/native/services/surfaceflinger/Client.cpp

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

这里,我们可以看到,创建surface时先是创建了一个MessageCreateLayer对象,他是MessageBase类的一个子类,MessageBase类在构造方法中先会调用handler()方法,此时就会通知SurfaceFlinger去创建Layer用来储存每一层画面的信息

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)
{
   ···
    sp<Layer> layer;

    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceNormal:
            result = createNormalLayer(client,
                    name, w, h, flags, format,
                    handle, gbp, &layer);
            break;
        case ISurfaceComposerClient::eFXSurfaceDim:
            result = createDimLayer(client,
                    name, w, h, flags,
                    handle, gbp, &layer);
            break;
        default:
            result = BAD_VALUE;
            break;
    }

    if (result != NO_ERROR) {
        return result;
    }

    result = addClientLayer(client, *handle, *gbp, layer);
    if (result != NO_ERROR) {
        return result;
    }

    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)
{
        ···

    *outLayer = new Layer(this, client, name, w, h, flags);
    status_t err = (*outLayer)->setBuffers(w, h, format, flags);
    if (err == NO_ERROR) {
        *handle = (*outLayer)->getHandle();
        *gbp = (*outLayer)->getProducer();
    }

    ALOGE_IF(err, "createNormalLayer() failed (%s)", strerror(-err));
    return err;
}

status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
        const String8& name, uint32_t w, uint32_t h, uint32_t flags,
        sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp, sp<Layer>* outLayer)
{
    *outLayer = new LayerDim(this, client, name, w, h, flags);
    *handle = (*outLayer)->getHandle();
    *gbp = (*outLayer)->getProducer();
    return NO_ERROR;
}

从上面的代码可以看到,两种创建Layer的方式都是为将新建的这个Layer对象的binder和gbp存储在上面的client对象中

 DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;

我们可以看到在Client的头文件中有着这样的定义,他是通过键值对来管理Layer的,这样client对象就能够与之通信并且管理这个layer了。

sp<IGraphicBufferProducer> getProducer() const;

在Layer的头文件中,我们可以查阅到getProducer返回的是一个IGraphicBufferProducer对象,所以gbp就是一个IGraphicBufferProducer对象,这个对象主要用来管理buffer,这里IGraphicBufferProducer就是app和BufferQueue重要桥梁,GraphicBufferProducer承担着单个应用进程中的UI显示需求,与BufferQueue打交道的就是它。

到这里,一个surface就基本创建完成。接着还有一部分就是在绘制view时,所调用的

 private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
            throws OutOfResourcesException;

方法。这个方法就是锁定了一个要更新的区域,然后返回他的画布,

xref: /frameworks/base/core/jni/android_view_Surface.cpp

291 static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
292        jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
293    sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
294
        ···
302
311    ANativeWindow_Buffer outBuffer;
312    status_t err = surface->lock(&outBuffer, dirtyRectPtr);
        ···
320
321
322    SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
323                                         convertPixelFormat(outBuffer.format),
324                                         outBuffer.format == PIXEL_FORMAT_RGBX_8888 ?
325                                         kOpaque_SkAlphaType : kPremul_SkAlphaType);
326
327    SkBitmap bitmap;
328    ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
329    bitmap.setInfo(info, bpr);
330    if (outBuffer.width > 0 && outBuffer.height > 0) {
331        bitmap.setPixels(outBuffer.bits);
332    } else {
333        // be safe with an empty bitmap.
334        bitmap.setPixels(NULL);
335    }
336
337    Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
338    nativeCanvas->setBitmap(bitmap);
339
        ···
357    return (jlong) lockedSurface.get();
358}

xref: /frameworks/native/libs/gui/Surface.cpp

1159 status_t Surface::lock(
1160        ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
1161{
        ```
1178    status_t err = dequeueBuffer(&out, &fenceFd);
1179    ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
1180    if (err == NO_ERROR) {
        ```
1250    return err;
1251}

231 int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
232    ATRACE_CALL();
233    ALOGV("Surface::dequeueBuffer");
234
235    uint32_t reqWidth;
236    uint32_t reqHeight;
237    PixelFormat reqFormat;
238    uint32_t reqUsage;
239
240    {
        ```
262    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
263            reqWidth, reqHeight, reqFormat, reqUsage);
264
        ````
313
314    return OK;
315     }

在锁定画布之后,就只有他自己可以使用,别人无法使用,锁定时由先前Client创建的GraphicBufferProducer对象来申请buffer进行绘制使用。

总结一下,SurfaceConrtrol是一个用来存储Surface的对象,关联Java层和native层,SurfaceSession用来创建SurfaceComposerClient,利用binder连接SurfaceFlinger,SurfaceFlinger作为一个单独的进程,靠Client来管理每个app的Surface,一个app只存在一个Client,一个Client可以通过binder管理多个Layer,Layer在创建时会构造一个IGraphicBufferProducer对象,用于后面在Surface上绘制时来申请Buffer

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值