Surface显示原理(从WMS往下看)

简介

其实这篇写的很烂,因为很多概念我没有清楚,但是足够反映一些认知上的问题。

我们看到的Surface其实不是Surface是Layer,Layer就是我们宏观的层级的概念,他里面有生产者消费者,生产者顾名思义就是产生界面,消费者就是消费界面将界面进行消费显示。所以今天主要是更正一个认知,至少我之前是认为,Surface就是一块画布。其实这样理解没有错,但是不准确,准确的时Suface时一个层,这个层上有有人生产有人消费。

我们在看一下我们第一次总结的调用在图:

ActivityThread.handleLaunchActivity()
    Activity a = performLaunchActivity()
        activity = mInstrumentation.newActivity()
        activity.attach()
            mWindow = new PhoneWindow(this);
            mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)...);
                mWindowManager = ((WindowManagerImpl)mContext.getSystemService("window")).createLocalWindowManager(this);
                    return new WindowManagerImpl(mDisplay, parentWindow)
            mWindowManager = mWindow.getWindowManager()
        mInstrumentation.callActivityOnCreate(activity...)
            activity.performCreate(...)
                onCreate(...)
                    setContentView(R.id.xx)
                        getWindow().setContentView(layoutResID);
                            PhoneWindow.installDecor()
                                generateDecor()
                                    return new DecorView();
    handleResumeActivity()
        wm.addView(decor...)
            mGlobal.addView(view...)
                root = new ViewRootImpl(...)
                    Surface mSurface = new Surface()//成员变量
                    mWindowSession = WindowManagerGlobal.getWindowSession()
                        IWindowManager windowManager = getWindowManagerService()
                            sWindowManagerService = IWindowManager.Stub.asInterface(ServiceManager.getService("window"))
                        sWindowSession = windowManager.openSession()
                            Session session = new Session()//在WMS中
                    mWindow = new W(this)//构造函数
                root.setView(view...)
                    mWindowSession.addToDisplay(mWindow...)
                        return mService.addWindow(...)//mService是WMS
                            token = new WindowToken(...)
                            WindowState win = new WindowState(...)
                            win.attach()
                                mSession.windowAddedLocked();
                                    mSurfaceSession = new SurfaceSession();
                            mWindowMap.put(client.asBinder(), win)//将这个window加入列表中
                    requestLayout()
                        scheduleTraversals()
                            run(){doTraversal()}
                                performTraversals()

上节课我们分析到了这里

root.setView(view...)
        mWindowSession.addToDisplay(mWindow...)
            return mService.addWindow(...)//mService是WMS
                Session.relayoutWindow()
                    token = new WindowToken(...)
                    WindowState win = new WindowState(...)
                    win.attach()
                        mSession.windowAddedLocked();
                            mSurfaceSession = new SurfaceSession();
                    mWindowMap.put(client.asBinder(), win)//将这个window加入列表中
        requestLayout()
            scheduleTraversals()
                run(){doTraversal()}
                    performTraversals()

在WMS中调用了Session的relayoutWindow

    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) {
            
            WindowState win = windowForClientLocked(session, client, false);
            WindowStateAnimator winAnimator = win.mWinAnimator;
            ...
            try {
                if (!win.mHasSurface) {
                    surfaceChanged = true;
                }
                SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
                if (surfaceControl != null) {
                    outSurface.copyFrom(surfaceControl);
                } else {
                    outSurface.release();
                }
            } catch (Exception e) {
                return 0;
            }
            ...
    }

我们先看看win.mWinAnimator如何创建

  final WindowState windowForClientLocked(Session session, IWindow client,
            boolean throwOnError) {
        return windowForClientLocked(session, client.asBinder(), throwOnError);
    }

    final WindowState windowForClientLocked(Session session, IBinder client,
            boolean throwOnError) {
        WindowState win = mWindowMap.get(client);
        return win;
    }

我们看见是从mWindowMap中得到:

    public int addWindow(Session session, IWindow client, int seq,
            WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
            Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
            InputChannel outInputChannel) {
            WindowState win = new WindowState(...);
            win.attach();
            mWindowMap.put(client.asBinder(), win);
    }

也就是说windowForClientLocked方法中拿到的是在addWindow时候生成的WindowState

那么winAnimator.createSurfaceLocked();是如何把SurfaceControl给整出来的
我们只能使劲研究:

SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
SurfaceControl createSurfaceLocked() {
    ...
    mSurfaceControl = new SurfaceControl(mSession.mSurfaceSession,
                        attrs.getTitle().toString(),
                        width, height, format, flags);
    ...
}
    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");
    }
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());
}

class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
{
public:
    BpSurfaceComposerClient(const sp<IBinder>& impl)
        : BpInterface<ISurfaceComposerClient>(impl) {
    }

    virtual ~BpSurfaceComposerClient();

    virtual status_t createSurface(const String8& name, uint32_t width,
            uint32_t height, PixelFormat format, uint32_t flags,
            sp<IBinder>* handle,
            sp<IGraphicBufferProducer>* gbp) {
        Parcel data, reply;
        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
        data.writeString8(name);
        data.writeUint32(width);
        data.writeUint32(height);
        data.writeInt32(static_cast<int32_t>(format));
        data.writeUint32(flags);
        remote()->transact(CREATE_SURFACE, data, &reply);
        *handle = reply.readStrongBinder();
        *gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
        return reply.readInt32();
    }

我们可以看出来SurfaceComposerClient创建Surface,这个SurfaceComposerClient是一个Binder对象,这边代理发消息,然后对端接收。

SurfaceComposerClient类是从RefBase派生所以:

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

其实目的很明确就是得到SurfaceComposerClient指针
,这个时候还要明白,SurfaceComposerClient时ComposerService的客户端。这个ComposerService实现了和SurfaceFlinger的关系,他把SurfaceFlinger服务包括在里面。

那我们就看看

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

看到其实时在mComposerService中包装着SurfaceFlinger

也就是说,SurfaceComposerClient对象时ComposerService的客户端,而ComposerService代理的时SurfaceFlinger。下次直接调用在SurfaceFlinger中找。

那之前:

   sp<SurfaceControl> surface = client->createSurface(
            String8(name.c_str()), w, h, format, flags);

这个调用就好解释多了,就去SurfaceFlinger中去找就对了。

握操没找到,怎么办,那我们再看看是不是继续SurfaceFlinger代理这谁。

从这个方法开始:

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。所以在client中找。

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

这段又跑到esult = flinger->createLayer(name, client, w, h, format, flags,
handle, gbp);

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的概念。

我们在说一点下,就是SurfaceComposerClient链接链接最后到了Client中,然后通过Client去实现一些东东比如创建层。其实这里我们在模糊一下概念,我们创建的Surface其实时Layer,

我们再看代码

    *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();
    }
status_t Layer::setBuffers( uint32_t w, uint32_t h,
                            PixelFormat format, uint32_t flags)
{
    uint32_t const maxSurfaceDims = min(
            mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());

    // never allow a surface larger than what our underlying GL implementation
    // can handle.
    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
        return BAD_VALUE;
    }

    mFormat = format;

    mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
    mCurrentOpacity = getOpacityForFormat(format);

    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
    mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));

    return NO_ERROR;
}
sp<IBinder> Layer::getHandle() {
    Mutex::Autolock _l(mLock);

    LOG_ALWAYS_FATAL_IF(mHasSurface,
            "Layer::getHandle() has already been called");

    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::getProducer() const {
    return mProducer;//    sp<IGraphicBufferProducer> mProducer;
}
void Layer::onFirstRef() {
    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    BufferQueue::createBufferQueue(&producer, &consumer);
    mProducer = new MonitoredProducer(producer, mFlinger);
    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
    mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
    mSurfaceFlingerConsumer->setContentsChangedListener(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);
}

现在说明冒出来很多概念

生产者,消费者,BufferQueue,这是要闹那样。

我们下次分析。

重点分析

在WMS中调用了Session的relayoutWindow

    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) {
            
            WindowState win = windowForClientLocked(session, client, false);
            WindowStateAnimator winAnimator = win.mWinAnimator;
            ...
            try {
                if (!win.mHasSurface) {
                    surfaceChanged = true;
                }
                SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
                if (surfaceControl != null) {
                    outSurface.copyFrom(surfaceControl);
                } else {
                    outSurface.release();
                }
            } catch (Exception e) {
                return 0;
            }
            ...
    }

执行outSurface.copyFrom(surfaceControl);的时候我们看看:

    public void copyFrom(SurfaceControl other) {
        ...
        long surfaceControlPtr = other.mNativeObject;
        ...
        long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
        synchronized (mLock) {
            if (mNativeObject != 0) {
                nativeRelease(mNativeObject);
            }
            setNativeObjectLocked(newNativeObject);
        }
    }
static jlong nativeCreateFromSurfaceControl(JNIEnv* env, jclass clazz,
        jlong surfaceControlNativeObj) {
    sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
    sp<Surface> surface(ctrl->getSurface());
    if (surface != NULL) {
        surface->incStrong(&sRefBaseOwner);
    }
    return reinterpret_cast<jlong>(surface.get());
}

我们看出来,surfaceControlPtr代表的时native层的SurfaceControl对象,然后通过native层的SurfaceControl对象得到Surface

sp<Surface> SurfaceControl::getSurface() const
{
    Mutex::Autolock _l(mLock);
    if (mSurfaceData == 0) {
        mSurfaceData = new Surface(mGraphicBufferProducer, false);
    }
    return mSurfaceData;
}

所以创建一个Surface,然后返回。

我们看到创建Surface的时候会传递mGraphicBufferProducer,这个是什么?

看到上面的分析,是不是就知道这个在Layer第一次调用的时候就有值了,是一个生产者。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容