应用获取画布surface流程

耗尽温柔 提交于 2019-11-27 08:37:40

    前面我们已经分析了activity通过SurfaceComposerClient在surfaceflinger服务中创建了一个Client。在本文中,我们将详细分析应用获取画布Surface流程。在分析Surface创建流程时,会涉及显示缓冲区队列相关知识,本文只是简单一笔带过,将在后面做具体分析。

1、申请创建Surface

1.1 viewrootImpl.java

在应用启动时,会通过WindowManagerGlobal去添加view,添加view时会去创建viewrootImpl,然后进行设置view。

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    。。。。。。
    requestLayout();//申请布局
    。。。。。。
}

requestLayout()—>scheduleTraversals()—>doTraversal()–>performTraversals()

    private void performTraversals() {
        。。。。。。
        //① 调用relayoutWindow,创建surface
        relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
        。。。。。。
    }   
  private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
            boolean insetsPending) throws RemoteException {
            //binder,调用Session的relayout,返回填充的mSurface
               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);     
            }

利用IWindowSession和Session通信,调用relayout,注意,这里mSurface是ViewRootImpl的成员变量,开始调用了无参的构造函数,IWindowSession.aidl文件中,参数mSurface是被out修饰,用来接受在server端创建Surface,然后再binder返回给ViewRootImpl。

1.2 Session.java

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

1.3 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, Configuration outConfig, Surface outSurface) {

          //新建一个SurfaceControl 
          SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
                  if (surfaceControl != null) {
                      outSurface.copyFrom(surfaceControl);
                      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();
                  }
          }

1.4 WindowStateAnimator.java

首先创建一个SurfaceControl,

    SurfaceControl createSurfaceLocked() {

            mSurfaceControl = new SurfaceControl(
                        mSession.mSurfaceSession,
                        attrs.getTitle().toString(),
                        w, h, format, flags);
             }

    public SurfaceControl(SurfaceSession session,
            String name, int w, int h, int format, int flags)
                    throws OutOfResourcesException {
              //session就是SurfaceComposerClient在java层的代表
              //mNativeObject是native层SurfaceControl的指针
    mNativeObject = nativeCreate(session, name, w, h, format, flags);
    }

1.5 android_view_SurfaceControl.cpp

static jint nativeCreate(JNIEnv* env, jclass clazz, jobject sessionObj,
        jstring nameStr, jint w, jint h, jint format, jint flags) {
    ScopedUtfChars name(env, nameStr);
    //从上层取到SurfaceComposerClient的指针,还原一个SurfaceComposerClient
    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
    //调用createSurface,返回的是一个SurfaceControl对象,注意不是surface
    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);
    //返回给java层SurfaceControl的指针
    return int(surface.get());
}

1.6 SurfaceComposerClient.cpp

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);
        //gbp就是surfacefligner中Layer的mBufferQueue的client端(IGraphicBufferProducer) 
        if (err == NO_ERROR) {
            sur = new SurfaceControl(this, handle, gbp);
        }
    }
    return sur;
}

1.7 Client.cpp

通过ISurfaceComposerClient的binder通信,调用服务端对应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)
{
    /*
     * 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; }
        //MessageQueue.cpp 中方法回调MessageBase::handleMessage
        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();
}

上述可看出,将创建layer消息放入队列,如下所示:

status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
        nsecs_t reltime, uint32_t /* flags */) {
    status_t res = mEventQueue.postMessage(msg, reltime);
    if (res == NO_ERROR) {
        //阻塞等待消息处理完成
        msg->wait();
    }
    return res;
}

1.8 Layer.cpp

当创建layer的消息被处理时,就会回调上述MessageCreateLayer类中的handler方法。handler方法中调用flinger.createLayer(),第一次还会执行Layer.onFirstRef()

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)
{
    //ALOGD("createLayer for (%d x %d), name=%s", w, h, name.string());
    if (int32_t(w|h) < 0) {
        ALOGE("createLayer() failed, w or h is negative (w=%d, h=%d)",
                int(w), int(h));
        return BAD_VALUE;
    }

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

在执行Layer::onFirstRef()会新建一个缓冲区队列的消费者与客户端APP的生产者对应

void Layer::onFirstRef()
{
    //surfaceflinger中新建一个缓冲区队列的消费者
    mBufferQueue = new SurfaceTextureLayer(mFlinger);
    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(mBufferQueue, mTextureName);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mSurfaceFlingerConsumer->setFrameAvailableListener(this);
    mSurfaceFlingerConsumer->setName(mName);

#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
#warning "disabling triple buffering"
    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(2);
#else
    mSurfaceFlingerConsumer->setDefaultMaxBufferCount(3);
#endif

    const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
    updateTransformHint(hw);
} 

2、获取创建好的Surface对象

WindowManagerService.java

 outSurface.copyFrom(surfaceControl);

之所以调用copyFrom()是因为拷贝的不是Java的对象,而是native本地对象。

Surface.java

    public void copyFrom(SurfaceControl other) {
        //native中的surfaceControl的指针
        int surfaceControlPtr = other.mNativeObject;

        int newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);//见2.1.1节

        synchronized (mLock) {
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
            }
            setNativeObjectLocked(newNativeObject);//见2.2.1节
        }
    }

2.1.1 android_view_Surface.cpp

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.
     */
     //强制转换为本地SurfaceControl
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
    //新建一个surface
    sp<Surface> surface(ctrl->getSurface());
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner);
    }
    //返回给java层surface的指针
    return reinterpret_cast<jint>(surface.get());
}

2.1.2 SurfaceControl.cpp

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.
        //新建surface,输入参数为BufferQueue的cleint端
        mSurfaceData = new Surface(mGraphicBufferProducer, false);
    }
    return mSurfaceData;
}

2.2.1 Surface.java

  private void setNativeObjectLocked(int ptr) {
        if (mNativeObject != ptr) {
            if (mNativeObject == 0 && ptr != 0) {
                mCloseGuard.open("release");
            } else if (mNativeObject != 0 && ptr == 0) {
                mCloseGuard.close();
            }
            //将java层surface的mNativeObject 设置为native层surface的指针
            mNativeObject = ptr;
            mGenerationId += 1;
        }
    }

3、binder回传给ViewRootImpl

通过IWindowSession.java进行aidl接口方式的binder远程调用。

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.graphics.Rect outStableInsets, android.graphics.Rect outOutsets, android.content.res.Configuration outConfig, android.view.Surface outSurface) throws android.os.RemoteException
{
  。。。。。。
if ((0!=_reply.readInt())) {
outSurface.readFromParcel(_reply);
}
 。。。。。。
}

3.1 Surface.java

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();
            //将natvice的surface对象的指针设置到java层
            setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source));
        }
    }

3.2 android_view_Surface.cpp

static jint nativeReadFromParcel(JNIEnv* env, jclass clazz,
        jint nativeObject, jobject parcelObj) {
    Parcel* parcel = parcelForJavaObject(env, parcelObj);
    if (parcel == NULL) {
        doThrowNPE(env);
        return 0;
    }

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

    //有可能这个surface已经构造过了,如果IGraphicBufferProducer变化了才会继续走到下面
    // 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;
    //重构BufferQueue的代理对象,即BpGraphicBufferProducer
    sp<IGraphicBufferProducer> gbp(interface_cast<IGraphicBufferProducer>(binder));
    if (gbp != NULL) {
        // we have a new IGraphicBufferProducer, create a new Surface for it
        //新建Surface
        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);
    }
    //返回给java层Surface的指针
    return int(sur.get());
}

4、流程图

这里写图片描述

5、总结

本文分析了surface创建流程,但是在创建流程过程中还涉及到显示系统的生产者与消费者模型,这个将在下一篇文章作分享,未完待续。。。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!