gui学习

317 阅读4分钟

BufferQueue

ConsumerListener是BufferQueue用来通知消费者的回调(消费者订阅消息,生产者生产消息时,将一些事件通知消费者)

typedef ::android::ConsumerListener ConsumerListener;
/*class ConsumerListener : public virtual RefBase {*/

IConsumerListener

ProxyConsumerListener 消费者使用IBinder对ConsumerListener回调的封装,可跨进程,使IConsumerListener在生产者进程中,并及时触发相关事件

class IConsumerListener : public ConsumerListener, public IInterface {
class ProxyConsumerListener : public BnConsumerListener {
        void onFrameAvailable(const BufferItem& item) override;
        wp<ConsumerListener> mConsumerListener;
}

BufferQueue管理buffer队列,并通过两个接口IGraphicBufferProducer和IGraphicBufferConsumer,向生产者和消费者提供生产buffer和消费buffer的能力

这两个接口是IBinder对象,可跨进程传输,最大程度解耦

static void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
        sp<IGraphicBufferConsumer>* outConsumer,
        bool consumerIsSurfaceFlinger = false);

sp<BufferQueueCore> core(new BufferQueueCore());
sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));

BufferItem

BufferItem主要是对GraphicBuffer和Fence的封装

class BufferItem : public Flattenable<BufferItem> {
    // mGraphicBuffer points to the buffer allocated for this slot, or is NULL
    // if the buffer in this slot has been acquired in the past (see
    // BufferSlot.mAcquireCalled).
    sp<GraphicBuffer> mGraphicBuffer;

    // mFence is a fence that will signal when the buffer is idle.
    sp<Fence> mFence;
    int mSlot;

BufferQueueCore

mQueue(Fifo)便是buffer所在队列

class BufferQueueCore : public virtual RefBase {

    friend class BufferQueueProducer;
    friend class BufferQueueConsumer;

    typedef Vector<BufferItem> Fifo;

    // mConsumerListener is used to notify the connected consumer of
    // asynchronous events that it may wish to react to. It is initially
    // set to NULL and is written by consumerConnect and consumerDisconnect.
    sp<IConsumerListener> mConsumerListener;
    
    // mLinkedToDeath is used to set a binder death notification on
    // the producer.
    sp<IProducerListener> mLinkedToDeath;

    // mConnectedProducerListener is used to handle the onBufferReleased
    // and onBuffersDiscarded notification.
    sp<IProducerListener> mConnectedProducerListener;
    
    BufferQueueDefs::SlotsType mSlots;
    // mQueue is a FIFO of queued buffers used in synchronous mode.
    Fifo mQueue;

IProducerListener

class ProducerListener : public virtual RefBase
{
public:
    ProducerListener() {}
    virtual ~ProducerListener();

    // onBufferReleased is called from IGraphicBufferConsumer::releaseBuffer to
    // notify the producer that a new buffer is free and ready to be dequeued.
    //
    // This is called without any lock held and can be called concurrently by
    // multiple threads.
    virtual void onBufferReleased() = 0; // Asynchronous
    virtual bool needsReleaseNotify() = 0;
    // onBuffersFreed is called from IGraphicBufferConsumer::discardFreeBuffers
    // to notify the producer that certain free buffers are discarded by the consumer.
    virtual void onBuffersDiscarded(const std::vector<int32_t>& slots) = 0; // Asynchronous
};

class IProducerListener : public ProducerListener, public IInterface
{

IGraphicBufferConsumer

class IGraphicBufferConsumer : public RefBase {
    
acquireBuffer
releaseBuffer
consumerConnect
    
class IGraphicBufferProducer : public RefBase {
requestBuffer
dequeueBuffer
queueBuffer
connect

ConsumerBase

ConsumerBase是消费者相关接口的初步封装,FrameAvailableListener是ConsumerBase收到回调的转发消息

class ConsumerBase : public virtual RefBase,
        protected ConsumerListener {

    struct FrameAvailableListener : public virtual RefBase {
        // See IConsumerListener::onFrame{Available,Replaced}
        virtual void onFrameAvailable(const BufferItem& item) = 0;
        virtual void onFrameReplaced(const BufferItem& /* item */) {}
        virtual void onFrameDequeued(const uint64_t){};
        virtual void onFrameCancelled(const uint64_t){};
        virtual void onFrameDetached(const uint64_t){};
    };

    wp<FrameAvailableListener> mFrameAvailableListener;

    // The ConsumerBase has-a BufferQueue and is responsible for creating this object
    // if none is supplied
    sp<IGraphicBufferConsumer> mConsumer;

Surface

Surface是对生产者相关接口的封装

eglSwapBuffers ---> ANativeWindow ---> Surface ---> IGraphicBufferProducer ---> GLConsumer

/*For example, a video decoder could render a frame and call
 * eglSwapBuffers(), which invokes ANativeWindow callbacks defined by
 * Surface.  Surface then forwards the buffers through Binder IPC
 * to the BufferQueue's producer interface, providing the new frame to a
 * consumer such as GLConsumer.
 */ 
class Surface
    : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
{

gui的架构大致如下:

BufferQueue管理Buffer队列,并通过IGraphicBufferConsumer和IGraphicBufferProducer向生产者 (app或sf)、消费者 (app或sf)提供服务

生产者和消费者在注册BufferQueue时,提供回调接口IProducerListener和IConsumerListener。当事件发生时,由BufferQueue通知

image-20220702093405194

DisplayEventDispatcher

class DisplayEventDispatcher : public LooperCallback {
    sp<Looper> mLooper;
    DisplayEventReceiver mReceiver;

DisplayEventReceiver

DisplayEventReceiver creates and registers an event connection with SurfaceFlinger

class DisplayEventReceiver {
    sp<IDisplayEventConnection> mEventConnection;
    std::unique_ptr<gui::BitTube> mDataChannel;

IDisplayEventConnection

class IDisplayEventConnection : public IInterface {

scheduleVsync

请求Vsync事件,通过mEventConnection向sf请求

DisplayEventDispatcher将mReceiver的channel的read端注册监听,当事件发生后,channel的write端写,回调到handleEvent的dispatchVsync中

在这个文件android/view/DisplayEventReceiver.java

int rc = mLooper->addFd(mReceiver.getFd(), 0, Looper::EVENT_INPUT, this, NULL);
status_t DisplayEventDispatcher::scheduleVsync() {
	status_t status = mReceiver.requestNextVsync();
    
status_t DisplayEventReceiver::requestNextVsync() {
    if (mEventConnection != nullptr) {
        mEventConnection->requestNextVsync();

ISurfaceComposer

ISurfaceComposer是sf服务对外暴露的接口。

createConnection是app向sf申请创建surface的方法

createDisplayEventConnection是app向sf注册vsync事件

class ISurfaceComposer: public IInterface {
public:
    DECLARE_META_INTERFACE(SurfaceComposer)
        
        
    enum VsyncSource {
        eVsyncSourceApp = 0,
        eVsyncSourceSurfaceFlinger = 1
    };
    
    /*
     * Create a connection with SurfaceFlinger.
     */
    virtual sp<ISurfaceComposerClient> createConnection() = 0;

    /* return an IDisplayEventConnection */
    virtual sp<IDisplayEventConnection> createDisplayEventConnection(
        
class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {
public:
    enum ISurfaceComposerTag {     

BufferQueueConsumer.CPP

status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
        const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
        EGLSyncKHR eglFence) {
    sp<IProducerListener> listener;
    { // Autolock scope
        std::lock_guard<std::mutex> lock(mCore->mMutex);

        mSlots[slot].mEglDisplay = eglDisplay;
        mSlots[slot].mEglFence = eglFence;
        mSlots[slot].mFence = releaseFence;
        mSlots[slot].mBufferState.release();
        
        // Don't put the shared buffer on the free list.
        if (!mSlots[slot].mBufferState.isShared()) {
            mCore->mActiveBuffers.erase(slot);
            mCore->mFreeBuffers.push_back(slot);
        }
        
        mCore->mDequeueCondition.notify_all();
    if (listener != nullptr) {
        listener->onBufferReleased();
    }
        
        
            std::lock_guard<std::mutex> lock(mCore->mMutex);

            if (error == NO_ERROR && !mCore->mIsAbandoned) {
                graphicBuffer->setGenerationNumber(mCore->mGenerationNumber);
                mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
                if (mCore->mConsumerListener != nullptr) {
                    mCore->mConsumerListener->onFrameDequeued(
                            mSlots[*outSlot].mGraphicBuffer->getId());
                }
            }
EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0,
                                     
        const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);

SurfaceFlinger

CompositionRefreshArgs

using Layers = std::vector<sp<compositionengine::LayerFE>>;
using Outputs = std::vector<std::shared_ptr<compositionengine::Output>>;

struct CompositionRefreshArgs {
    // All the outputs being refreshed
    Outputs outputs;

    // All the layers that are potentially visible in the outputs. The order of
    // the layers is important, and should be in traversal order from back to
    // front.
    Layers layers;

    // All the layers that have queued updates.
    Layers layersWithQueuedFrames;
    
    // The color matrix to use for this
    // frame. Only set if the color transform is changing this frame.
    std::optional<mat4> colorTransformMatrix;

ClientCompositionTargetSettings

      struct ClientCompositionTargetSettings {
          enum class BlurSetting {
              Disabled,
              BackgroundBlurOnly,
              BlurRegionsOnly,
              Enabled,
          };

          // Configure layer settings for using blurs
          BlurSetting blurSetting;
    struct FrameFences {
        sp<Fence> presentFence{Fence::NO_FENCE};
        sp<Fence> clientTargetAcquireFence{Fence::NO_FENCE};
        std::unordered_map<HWC2::Layer*, sp<Fence>> layerFences;
    };

    virtual FrameFences presentAndGetFrameFences() = 0;