美文网首页收藏
显示框架之app与SurfaceFlinger通信

显示框架之app与SurfaceFlinger通信

作者: Android图形显示之路 | 来源:发表于2022-03-31 16:54 被阅读0次

SurfaceFlinger是android显示的核心进程,在整个显示框架中起到一个承上启下的作用,“承上”指的是与app进程间的通信,“启下”指的是与Composer进程的通信。Surfaceflinger本身不进行绘制,是app数据上屏的中枢通路,先来看下SurfaceFlinger在整个显示流程中的位置。


显示流程图.png

从显示流程图看可知,SurfaceFlinger位于中间层的位置,目前的应用会调起renderthread使用GPU来渲染,应用侧使用surface来管理显示数据,surfaceflinger使用layer来对应应用侧的surface,surfaceflinger会根据合成的方式,选择device还是GPU合成,最后将layer数据提交给Composer进程,进而通过display 驱动上屏。本文就来研究下app和SurfaceFlinger之间的通信,主要针对native层的分析,代码基于android11。

APP与SurfaceFlinger之间的连接

首先框架会创建surfaceControl来管理surface,在jni层会创建一个surfaceComposerClient对象,这个对象是负责与SurfaceFlinger进程通信的重要载体。

文件: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, jlong parentObject,
        jobject metadataParcel) {
    ScopedUtfChars name(env, nameStr);
    sp<SurfaceComposerClient> client;
    if (sessionObj != NULL) {
        client = android_view_SurfaceSession_getClient(env, sessionObj);
    } else {
         // 如果java侧没有该对象则创建SurfaceComposerClient对象
        client = SurfaceComposerClient::getDefault();
    }
    SurfaceControl *parent = reinterpret_cast<SurfaceControl*>(parentObject);
    sp<SurfaceControl> surface;
   ...
    // 通过SurfaceComposerClient创建一个Surface
    status_t err = client->createSurfaceChecked(
            String8(name.c_str()), w, h, format, &surface, flags, parent, std::move(metadata));
   ...
    // 返回给上层surface对象
    return reinterpret_cast<jlong>(surface.get());
}

文件:frameworks/native/libs/gui/SurfaceComposerClient.cpp 

sp<SurfaceComposerClient> SurfaceComposerClient::getDefault() {
    return DefaultComposerClient::getComposerClient();
 }

class DefaultComposerClient: public Singleton<DefaultComposerClient> {
    Mutex mLock;
    sp<SurfaceComposerClient> mClient;
    friend class Singleton<ComposerService>;
public:
    static sp<SurfaceComposerClient> getComposerClient() {
        // 使用单例模式创建DefaultComposerClient 对象
        DefaultComposerClient& dc = DefaultComposerClient::getInstance();
        Mutex::Autolock _l(dc.mLock);
        if (dc.mClient == nullptr) {
            // 创建SurfaceComposerClient 对象
            dc.mClient = new SurfaceComposerClient;
        }
        return dc.mClient;
    }
};
// 由于SurfaceComposerClient是sp指针,第一次创建时会执行onFirstRef 函数
void SurfaceComposerClient::onFirstRef() {
    sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
        conn = sf->createConnection();
        if (conn != nullptr) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}
//在getComposerService 函数中调connectLocked来get到SurfaceFlinger服务并注册了死亡监听
void ComposerService::connectLocked() {
    const String16 name("SurfaceFlinger");
    while (getService(name, &mComposerService) != NO_ERROR) {
        usleep(250000);
    }
    assert(mComposerService != nullptr);

    // 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:
        explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
    };

    mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
    IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}
文件:frameworks/native/services/surfaceflinger/surfaceflinger.cpp

// 与SurfaceFlinger建立联系,Client持有SurfaceFlinger对象
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    const sp<Client> client = new Client(this);
    return client->initCheck() == NO_ERROR ? client : nullptr;
}

看注释,至此完成了从SurfaceControl-> SurfaceComposerClient -> SurfaceFlinger的连接过程。应用要创建Surface时,对应SurfaceFlinger会创建layer与之对应。

文件:frameworks/native/libs/gui/SurfaceComposerClient.cpp 

status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
                                                     PixelFormat format,
                                                     sp<SurfaceControl>* outSurface, uint32_t flags,
                                                     SurfaceControl* parent, LayerMetadata metadata,
                                                     uint32_t* outTransformHint) {
    sp<SurfaceControl> sur;
    ...
        // 会执行到Client.cpp里面的createSurface
        err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
                                     &handle, &gbp, &transformHint);
       ...
        ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
        if (err == NO_ERROR) {
            // 根据返回的handle 和 gbp 创建 SurfaceControl
            *outSurface = new SurfaceControl(this, handle, gbp, transformHint);
        }
    }
    return err;
}

文件: frameworks/native/services/surfaceflinger/Client.cpp

status_t Client::createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
                               uint32_t flags, const sp<IBinder>& parentHandle,
                               LayerMetadata metadata, sp<IBinder>* handle,
                               sp<IGraphicBufferProducer>* gbp, uint32_t* outTransformHint) {
    // We rely on createLayer to check permissions.
    return mFlinger->createLayer(name, this, w, h, format, flags, std::move(metadata), handle, gbp,
                                 parentHandle, nullptr, outTransformHint);
}

文件: frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

tatus_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& client, uint32_t w,
                                     uint32_t h, PixelFormat format, uint32_t flags,
                                     LayerMetadata metadata, sp<IBinder>* handle,
                                     sp<IGraphicBufferProducer>* gbp,
                                     const sp<IBinder>& parentHandle, const sp<Layer>& parentLayer,
   ...
    sp<Layer> layer;
   ...
    switch (flags & ISurfaceComposerClient::eFXSurfaceMask) {
        case ISurfaceComposerClient::eFXSurfaceBufferQueue:
            // 对于surface类型创建layer类型,主要看下带有BufferQueue的layer
            result = createBufferQueueLayer(client, std::move(uniqueName), w, h, flags,
                                            std::move(metadata), format, handle, gbp, &layer);

            break;
    ...
    // 将创建的layer放到mCurrentState 里面,SurfaceFlinger内部管理了mCurrentState 和 mDrawingState
    result = addClientLayer(client, *handle, *gbp, layer, parentHandle, parentLayer,
                            addToCurrentState, outTransformHint);
    ...
    setTransactionFlags(eTransactionNeeded);
    return result;
}
文件: frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

status_t SurfaceFlinger::createBufferQueueLayer(const sp<Client>& client, std::string name,
                                                uint32_t w, uint32_t h, uint32_t flags,
                                                LayerMetadata metadata, PixelFormat& format,
                                                sp<IBinder>* handle,
                                                sp<IGraphicBufferProducer>* gbp,
                                                sp<Layer>* outLayer) {
    ...
    sp<BufferQueueLayer> layer;
    LayerCreationArgs args(this, client, std::move(name), w, h, flags, std::move(metadata));
    ...
        Mutex::Autolock lock(mStateLock);
        layer = getFactory().createBufferQueueLayer(args);
    ...
    if (err == NO_ERROR) {
         // 在surfaceflinger侧 new了一个handle,这个handle指向这个layer
        *handle = layer->getHandle();
        //gbp是创建的BufferQueueProducer对象
        *gbp = layer->getProducer();
        *outLayer = layer;
    }
        
    ALOGE_IF(err, "createBufferQueueLayer() failed (%s)", strerror(-err));
    return err;
}

文件: frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp

sp<BufferQueueLayer> DefaultFactory::createBufferQueueLayer(const LayerCreationArgs& args) {
    // new 了BufferQueueLayer对象,sp指针第一次创建时会执行onFirstRef 函数
    return new BufferQueueLayer(args);
}

文件:frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp

void BufferQueueLayer::onFirstRef() {
    BufferLayer::onFirstRef();

    // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferConsumer> consumer;
    // 创建一个BufferQueue对象,跟着创建一个BufferQueueCore, BufferQueueProducer和 BufferQueueConsumer对象
    mFlinger->getFactory().createBufferQueue(&producer, &consumer, true);
    // 对producer 的一个封装,MonitoredProducer实质与 producer无差别
    mProducer = mFlinger->getFactory().createMonitoredProducer(producer, mFlinger, this);
    // 创建BufferLayerConsumer ,首先创建父类ConsumerBase 对象
    mConsumer =
            mFlinger->getFactory().createBufferLayerConsumer(consumer, mFlinger->getRenderEngine(),
                                                             mTextureName, this);
   ...
    // 注册了一个监听,将BufferQueueLayer的函数方法注册到BufferQueueCore里面,说明当Buffer有变化时会通知BufferQueueLayer执行相应的动作
    mContentsChangedListener = new ContentsChangedListener(this);
    mConsumer->setContentsChangedListener(mContentsChangedListener);
    mConsumer->setName(String8(mName.data(), mName.size()));

    // BufferQueueCore::mMaxDequeuedBufferCount is default to 1
    // 设置producer最大dequeue的buffer数量
    if (!mFlinger->isLayerTripleBufferingDisabled()) {
        mProducer->setMaxDequeuedBufferCount(2);
    }
}

文件:frameworks/native/services/surfaceflinger/Layer.cpp

sp<IBinder> Layer::getHandle() {
    Mutex::Autolock _l(mLock);
    if (mGetHandleCalled) {
        ALOGE("Get handle called twice" );
        return nullptr;
    }
    mGetHandleCalled = true;
   // 创建一个handle对应layer
    return new Handle(mFlinger, this);
}

看注释,SurfaceFlinger侧创建了handle和GraphicsBufferProducer对象给到SurfaceControl,handle 指向surfaceflinger的layer,GraphicsBufferProducer 提供surface对Buffer的操作接口,上层操作surface的handle来作用到surfaceflinger的layer。至此,surfaceflinger创建layer的流程分析完了,比较绕的地方是涉及BufferQueue对象之间的关系,用一副类的关系图来说明之间的关系。


BufferQueue类图.png

APP与SurfaceFlinger之间数据的传递

现在应用一般采用GPU去渲染加速,GPU操作在RenderThread里(HWUI 里面的逻辑很复杂,后续会进行剖析),应用要绘制数据首先需要申请一块Buffer,由前面分析可知,应用是一个GraphicsBufferProducer的角色,故可以通过dequeueBuffer来向surfaceflinger申请一块Buffer。

DequeueBuffer

文件: frameworks/native/libs/gui/Surface.cpp

int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
    ATRACE_CALL();
    ALOGV("Surface::dequeueBuffer");

   ...
    // 从应用进程调到SurfaceFlinger进程,实现在SurfaceFlinger侧
    status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight,
                                                            reqFormat, reqUsage, &mBufferAge,
                                                            enableFrameTimestamps ? &frameTimestamps
                                                                                  : nullptr);
    ...
     // 后续会通过requestBuffer拿到Buffer
    sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);

    ...
        // requestBuffer将通过importBuffer将Buffer映射到应用进程
        result = mGraphicBufferProducer->requestBuffer(buf, &gbuf);
    ...
       *buffer = gbuf.get();
    ...

       mDequeuedSlots.insert(buf);
       return OK;
}

文件: frameworks/native/libs/gui/BufferQueueProducer.cpp
status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* outFence,
                                            uint32_t width, uint32_t height, PixelFormat format,
                                            uint64_t usage, uint64_t* outBufferAge,
                                            FrameEventHistoryDelta* outTimestamps) {
    ...
    int found = BufferItem::INVALID_BUFFER_SLOT;
    while (found == BufferItem::INVALID_BUFFER_SLOT) {
          // 优先从mFreeBuffers 里面获取slot, 若没有则从mFreeSlots 里面获取,从mFreeSlots 里面获取的都是还未分配Buffer的slot
          status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, lock, &found);
    ...
    }
    if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
        ...
        //若得到的slot对应的buffer为空则重新分配一块GraphicsBuffer
        sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(
                width, height, format, BQ_LAYER_COUNT, usage,
                {mConsumerName.string(), mConsumerName.size()});
        ...
        mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
        ...
}

文件: frameworks/native/libs/gui/BufferQueueProducer.cpp

status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
    ...
    mSlots[slot].mRequestBufferCalled = true;
     // GraphicsBuffer跨进程传递执行unflatten
    *buf = mSlots[slot].mGraphicBuffer;
    return NO_ERROR;
}

文件: frameworks/native/libs/ui/GraphicBuffer.cpp

status_t GraphicBuffer::unflatten(void const*& buffer, size_t& size, int const*& fds,
                                  size_t& count) {
...

if (handle != nullptr) {
        buffer_handle_t importedHandle;
        status_t err = mBufferMapper.importBuffer(handle, uint32_t(width), uint32_t(height),
                uint32_t(layerCount), format, usage, uint32_t(stride), &importedHandle);
...
        handle = importedHandle;
...

       return NO_ERROR;
}

应用的surface执行dequeueBuffer是在应用进程,具体实现是通过BufferQueueProducer的dequeueBuffer,是在SurfaceFlinger进程,所以需要通过requestBuffer将Buffer映射到应用进程,具体实现是通过importBuffer。真正分配Buffer的地方是在ion,ion是怎么分配Buffer的,以及Buffer怎么实现app和SurfaceFlinger共享,先用一张简图概述下,后续会分析。


Buffer共享.png

至此app就拿到了可绘制的Buffer,GPU可以将数据渲染到这块Buffer上。GPU将数据渲染到Buffer后,会执行eglSwapBuffers交换front和back buffer,eglSwapBuffers会调用queueBuffer,android系统用queueBuffer来请求vsync 唤醒SurfaceFlinger刷新。

queueBuffer

文件: frameworks/native/libs/gui/Surface.cpp

int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
    ...
     // dequeue出来的buffer对应的slot
    int i = getSlotFromBufferLocked(buffer);
    ...
    // 传入一些参数,其中 fenceFd 是由GPU带过来的,表示GPU渲染是否完成,这里为acquireFence
    IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
            static_cast<android_dataspace>(mDataSpace), crop, mScalingMode,
            mTransform ^ mStickyTransform, fence, mStickyTransform,
            mEnableFrameTimestamps);
    ...
    // 调到SurfaceFlinger进程的queueBuffer
    status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
    ...
}

文件: frameworks/native/libs/gui/BufferQueueProducer.cpp

status_t BufferQueueProducer::queueBuffer(int slot,
        const QueueBufferInput &input, QueueBufferOutput *output) {
...
    BufferItem item;
...
        // 将数据同步到item对象
        item.mAcquireCalled = mSlots[slot].mAcquireCalled;
        item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
        item.mCrop = crop;
        item.mTransform = transform &
                ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
        item.mTransformToDisplayInverse =
                (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
        item.mScalingMode = static_cast<uint32_t>(scalingMode);
        item.mTimestamp = requestedPresentTimestamp;
        item.mIsAutoTimestamp = isAutoTimestamp;
        item.mDataSpace = dataSpace;
        item.mHdrMetadata = hdrMetadata;
        item.mFrameNumber = currentFrameNumber;
        item.mSlot = slot;
        item.mFence = acquireFence;
        item.mFenceTime = acquireFenceTime;
        item.mIsDroppable = mCore->mAsyncMode ||
                (mConsumerIsSurfaceFlinger && mCore->mQueueBufferCanDrop) ||
                (mCore->mLegacyBufferDrop && mCore->mQueueBufferCanDrop) ||
                (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot);
        item.mSurfaceDamage = surfaceDamage;
        item.mQueuedBuffer = true;
        item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh;
        item.mApi = mCore->mConnectedApi;
       ...
      
       // 把item放到mQueue里面
       mCore->mQueue.push_back(item);
       // 这里的mCore->mConsumerListener 实际上为ConsumerBase对象
       frameAvailableListener = mCore->mConsumerListener;
       ...
      if (frameAvailableListener != nullptr) {
        frameAvailableListener->onFrameAvailable(item);
      }...
}

文件: frameworks/native/libs/gui/ConsumerBase.cpp

void ConsumerBase::onFrameAvailable(const BufferItem& item) {
    CB_LOGV("onFrameAvailable");

    sp<FrameAvailableListener> listener;
    { // scope for the lock
        Mutex::Autolock lock(mFrameAvailableMutex);
        listener = mFrameAvailableListener.promote();
    }

    if (listener != nullptr) {
        CB_LOGV("actually calling onFrameAvailable");
        // listener实际上是BufferQueueLayer对象
        listener->onFrameAvailable(item);
    }
}

根据类图关系,frameAvailableListener 实际上是ConsumerBase 对象,在ConsumerBase 初始化的时候进行赋值,通过 mConsumer->consumerConnect(proxy, controlledByApp)接口,所以会调到ConsumerBase::onFrameAvailable, 而mFrameAvailableListener 是BufferQueueLayer -> setContentsChangedListener(mContentsChangedListener) 设的,实际上是 BufferQueueLayer对象,因此最后走到BufferQueueLayer::onFrameAvailable 逻辑里面了。

文件: frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp

void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
   ...
    // 将item 放到mQueueItems里面
    mQueueItems.push_back(item);
    mQueuedFrames++;
   ...
    // 申请vsync去触发surfaceflinger刷新
    mFlinger->signalLayerUpdate();
    mConsumer->onBufferAvailable(item);
}

文件: frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp

void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
    if (connection->resyncCallback) {
        connection->resyncCallback();
    }
    std::lock_guard<std::mutex> lock(mMutex);

    if (connection->vsyncRequest == VSyncRequest::None) {
        // Vsync请求置为Single
        connection->vsyncRequest = VSyncRequest::Single;
        mCondition.notify_all();
    }
}

让Surfaceflinger刷新需要2个必要条件: 1. 有requestNextVsync 的请求 2. 软件vsync计算模型回调 onVSyncEvent创建一个vsyncEvent,涉及到vsync模型,后面会介绍。
到这里,app完成了与SurfaceFlinger的连接以及将应用数据传给到SurfaceFlinger。这里需要注意的是,其实SurfaceFlinger并不会动Buffer里面的数据,只是中间传递的一个过程,Buffer数据是由GPU渲染,display显示,下篇分析下SurfaceFlinger在刷新时做了哪些动作。

相关文章

网友评论

    本文标题:显示框架之app与SurfaceFlinger通信

    本文链接:https://www.haomeiwen.com/subject/xbjnjrtx.html