Android Surfaceflinger Service (i)-----bufferqueue analysis

Source: Internet
Author: User

Producer and consumer models are the most widely used models in programming. The model is also used to draw, synthesize, and display surfaceflinger images. This model is used to manage image buffer buffers reasonably. Keep the entire Android system from drawing to displaying in a methodical way.

Bufferqueue Image Buffer Manager. Its member function Createbufferqueue creates a buffer queue.

void Bufferqueue::createbufferqueue (sp<igraphicbufferproducer>* outproducer, SP&LT;IGRAPHICBUFFERCONSUMER&G                      t;* Outconsumer, const sp<igraphicbufferalloc>& allocator) {log_always_fatal_if (Outproducer = = NULL,    "Bufferqueue:outproducer must not being NULL");                                                                                                                                        log_always_fatal_if (Outconsumer = = NULL, "Bufferqueue:outconsumer must not being null"); S    P<bufferqueuecore> Core (new Bufferqueuecore (allocator));                                                                                                                                    Log_always_fatal_if (Core = = NULL, "bufferqueue:failed to create Bufferqueuecore"); Sp<igraphicbuf    Ferproducer> producer (new Bufferqueueproducer (CORE)); log_always_fatal_if (producer = = NULL, "Bufferqueue:Failed to create Bufferqueueproducer ");    Sp<igraphicbufferconsumer> Consumer (new Bufferqueueconsumer (CORE));                                                                                                                               log_always_fatal_if (consumer = = NULL, "bufferqueue:failed to create Bufferqueueconsumer");    *outproducer = producer; *outconsumer = consumer;}
    • outproducer outconsumer for output parameters, output corresponding producer interface, and consumer interface
    • allocator as input parameters, enter an image buffer memory allocation interface for memory application
    • First, general allocator constructs a Bufferqueuecore object and then constructs the Producer object (Bufferqueueproducer) and Consumer object (Bufferqueueconsumer)
    with the object.
Class Bufferqueuecore:public virtual Refbase {friend Class Bufferqueueproducer;  Friend class Bufferqueueconsumer;public://used as a placeholder slot number when the value is ' t pointing to AN//    Existing buffer.    enum {invalid_buffer_slot = Bufferitem::invalid_buffer_slot};    We reserve the slots in order to guarantee that the producer and//consumer can run asynchronously.    enum {max_max_acquired_buffers = bufferqueuedefs::num_buffer_slots-2};    The default API number used to indicate this no producer is connected enum {no_connected_api = 0};    typedef vector<bufferitem> FIFO; Bufferqueuecore manages a pool of gralloc memory slots to being used by//producers and consumers.    Allocator is used to allocate all the needed//Gralloc buffers.    Bufferqueuecore (const sp<igraphicbufferalloc>& allocator = NULL); Virtual ~bufferqueuecore ();p rivate://Dump our state in a string void Dump (string8& result, const char* prefix) const; getminundequeuedbuffercountlocked returns the minimum number of buffers//That must remain in a and other than DE QUEUED.    The async parameter//tells whether we ' re in asynchronous mode.    int getminundequeuedbuffercountlocked (bool async) const; getminmaxbuffercountlocked returns the minimum number of buffers allowed//Given the current bufferqueue state.    The async parameter tells whether//we ' re in asynchonous mode.    int getminmaxbuffercountlocked (bool async) const; Getmaxbuffercountlocked returns the maximum number of buffers that can is//allocated at once. This value depends the following member variables:////Mdequeuebuffercannotblock//Mmaxacquiredbuff Ercount//Mdefaultmaxbuffercount//Moverridemaxbuffercount//Async parameter////any time    One of these member variables is changed while a producer are//connected, mdequeuecondition must be broadcast. int GetmAxbuffercountlocked (bool async) const;  Setdefaultmaxbuffercountlocked sets the maximum number of buffer slots//That would be used if the producer does not Override the buffer slot//count. The count must be between 2 and num_buffer_slots, inclusive.    The//initial default is 2.    status_t setdefaultmaxbuffercountlocked (int count);    Freebufferlocked frees the Graphicbuffer and sync Resources for the//given slot.    void freebufferlocked (int slot);    Freeallbufferslocked frees the Graphicbuffer and sync Resources for//all slots.    void freeallbufferslocked ();    Stilltracking returns true IFF the buffer item is still being tracked//in one of the slots.    BOOL Stilltracking (const bufferitem* Item) const;    Waitwhileallocatinglocked blocks until misallocating is false.    void waitwhileallocatinglocked () const; Validateconsistencylocked ensures that the free lists is in sync with//The information stored in mslots void V Alidateconsistencylocked () const;    Mallocator is the connection to Surfaceflinger, that's used to allocate//new Graphicbuffer objects.    Sp<igraphicbufferalloc> Mallocator; Mmutex is the mutex used to prevent concurrent access to the member//variables of Bufferqueuecore objects.    It must be locked whenever any//member variable is accessed.    mutable Mutex Mmutex; Misabandoned indicates that the bufferqueue would no longer be used to//consume image buffers pushed to it using th e igraphicbufferproducer//interface. It is initialized to false, and set to true in the//Consumerdisconnect method.    A Bufferqueue that's abandoned would return//the No_init error from all Igraphicbufferproducer methods capable of    Returning an error.    BOOL misabandoned;    Mconsumercontrolledbyapp indicates whether the connected consumer is//controlled by the application.    BOOL Mconsumercontrolledbyapp; Mconsumername is a string used to IDEntify the Bufferqueue in Log//messages.    It is set by the Igraphicbufferconsumer::setconsumername//method.    String8 Mconsumername; Mconsumerlistener is used to notify the connected consumer of//asynchronous events, it may wish to react to.    It is initially//set to NULL and are written by Consumerconnect and Consumerdisconnect.    Sp<iconsumerlistener> Mconsumerlistener;    Mconsumerusagebits contains flags, the consumer wants for//graphicbuffers.    uint32_t mconsumerusagebits; Mconnectedapi indicates the producer API that's currently connected//to this bufferqueue.    It defaults to No_connected_api, and gets updated//by the Connect and disconnect methods.    int Mconnectedapi;    Mconnectedproducertoken is used to set a binder death notification on//the producer.    Sp<iproducerlistener> Mconnectedproducerlistener; Mslots is a array of buffer slots that must being mirrored on the producer//side. This Allows buffer ownership to being transferred between the producer//and consumer without sending a graphicbuffer over Bi NDEr. The entire//array is initialized-NULL at construction time, and buffers be//allocated for a slots when reques    Tbuffer is called with that slot ' s index.    Bufferqueuedefs::slotstype mslots;    Mqueue is a FIFO of queued buffers used in synchronous mode.    Fifo Mqueue; Mfreeslots contains all of the slots which is free and does not currently//has a buffer attached std::set<in    T> mfreeslots; Mfreebuffers contains all of the slots which is free and currently has//a buffer attached STD::LIST&LT;INT&GT ;    Mfreebuffers; Moverridemaxbuffercount is the limit on the number of buffers that would//be allocated at one time. This value was set by the producer by calling//Setbuffercount. The default is 0, which means, and the producer doesn ' t//care on the number of buffers in the pool. In the case,//Mdefaultmaxbuffercount is used as the limit.    int moverridemaxbuffercount;    Mdequeuecondition is a condition variable used for Dequeuebuffer in//synchronous mode.    mutable Condition mdequeuecondition;    Museasyncbuffer indicates whether an extra buffer was used in async mode//To prevent Dequeuebuffer from blocking.    BOOL Museasyncbuffer; Mdequeuebuffercannotblock Indicates whether Dequeuebuffer is allowed to//block.    This flag was set during connect when both the producer and//consumer was controlled by the application.    BOOL Mdequeuebuffercannotblock;    Mdefaultbufferformat can set so it would override the buffer format//When it is ' t specified in Dequeuebuffer.    PixelFormat Mdefaultbufferformat; Mdefaultwidth holds the default width of allocated buffers.    It is used//dequeuebuffer if a width and height of 0 are specified.    uint32_t mdefaultwidth; Mdefaultheight holds the default height of allocated buffers. IT is used//dequeuebuffer if a width and height of 0 are specified.    uint32_t mdefaultheight;    Mdefaultbufferdataspace holds the default dataspace of queued buffers.    It is used in Queuebuffer if a dataspace of 0 (Hal_dataspace_unknown)//is specified.    Android_dataspace Mdefaultbufferdataspace; Mdefaultmaxbuffercount is the default limit on the number of buffers//'ll be allocated at one time.    This default limit was set by the consumer.    The limit (as opposed to the default limit) is overriden by the//producer.    int mdefaultmaxbuffercount; Mmaxacquiredbuffercount is the number of buffers, the consumer may//acquire at one time. It defaults to 1, and can is changed by the consumer//via Setmaxacquiredbuffercount, but this is only is done while No//producer is connected to the Bufferqueue.    This value was used to derive//the value returned for the Min_undequeued_buffers query to the producer. int MmaxaCquiredbuffercount; Mbufferhasbeenqueued is true once a buffer has been queued.    It is reset/when something causes all buffers to be freed (e.g., changing the buffer//count).    BOOL mbufferhasbeenqueued; Mframecounter is the free running counter, incremented on every//successful Queuebuffer call and buffer allocation    .    uint64_t Mframecounter;    Mtransformhint is used to optimize for screen rotations.    uint32_t Mtransformhint;    Msidebandstream is a handle to the sideband buffer stream, if any sp<nativehandle> msidebandstream; Misallocating Indicates whether a producer is currently trying to allocate buffers (which//releases Mmutex while D Oing the allocation proper). Producers should not modify any of the//free slots and this is true.    Misallocatingcondition is signaled if this value changes to//False.    BOOL misallocating; Misallocatingcondition is a condition variable used by producers to wait until MisallOcating//becomes false.    mutable Condition misallocatingcondition;    Mallowallocation determines whether Dequeuebuffer is allowed to allocate//new buffers bool mallowallocation; Mbufferage tracks the age of the contents of the most recently dequeued//buffer as the number of frames that hav    e elapsed since it was last queued uint64_t mbufferage; Mgenerationnumber stores the current generation number of the attached//producer.    Any attempt to attach a buffer with a different generation//number would fail. uint32_t Mgenerationnumber;}; Class Bufferqueuecore
    • This class is a more critical class
    • member Variable mslots manages the status of each buffer in the queue
struct Bufferslot {bufferslot (): Megldisplay (Egl_no_display), Mbufferstate (Bufferslot::free), MREQUESTBU Ffercalled (False), Mframenumber (0), meglfence (Egl_no_sync_khr), macquirecalled (false), Mneedscleanupon Release (False), Mattachedbyconsumer (false) {}//Mgraphicbuffer points to the buffer allocated for this slot O    R is NULL//If no buffer has been allocated.    Sp<graphicbuffer> Mgraphicbuffer;    Megldisplay is the egldisplay used to create Eglsynckhr objects.    Egldisplay Megldisplay;  Bufferstate represents the different states in which a buffer slot//can be.    All slots is initially free.    Enum Bufferstate {free = 0, dequeued = 1, QUEUED = 2, acquired = 3};    static const char* Bufferstatename (bufferstate state);    Mbufferstate is the current state of this buffer slot.    Bufferstate mbufferstate;  Mrequestbuffercalled is used for validating, the producer did  Call Requestbuffer () when told to do.    Technically this isn't//needed but useful for debugging and catching producer bugs.    BOOL mrequestbuffercalled;  Mframenumber is the number of the queued frame for this slot. This//are used to dequeue buffers in LRU order (useful because buffers//may be released before their release Fenc    E is signaled).    uint64_t Mframenumber; Meglfence is the EGL Sync object, must signal before the buffer//associated with this buffer slot could be deque ued. It was initialized//to Egl_no_sync_khr when the buffer was created and May was set to a//new SYNC object in release  Buffer.    (This was deprecated in favor of//Mfence, below.)    Eglsynckhr meglfence; Mfence is a fence which would signal when work initiated by the//previous owner of the buffer is finished. When the buffer was free,//The fence indicates when the consumer had finished reading//from the buffer, or when t He producer has finishEd writing if it//called Cancelbuffer after queueing some writes. When the buffer was//QUEUED, it indicates when the producer had finished filling the//buffer. When the buffer is dequeued or acquired, the fence have been//passed to the consumer or producer along with ownership    of the//buffer, and mfence is set to No_fence.    Sp<fence> mfence;    Indicates whether this buffer have been seen by a consumer yet bool macquirecalled;  Indicates whether this buffer needs to is cleaned up by the//consumer.    This was set when a buffer of acquired state was freed.    It causes ReleaseBuffer to return Stale_buffer_slot.    BOOL Mneedscleanuponrelease;    Indicates whether the buffer was attached on the consumer side. If So, it needs to set the BUFFER_NEEDS_REALLOCATION flag when dequeued//To prevent the producer from using a Stal    e Cached buffer. bool Mattachedbyconsumer;};
    • Bufferstate defines five states of a buffer
    • The struct describes the state and properties of each buffer.

Bufferqueue production steps (Producer interface Bufferqueueproducer):

    1. Dequeuebuffer
    2. Requestbuffer
    3. Queuebuffer

Bufferqueue Consumption Steps (Consumer interface Bufferqueueconsumer):

    1. Acquirebuffer
    2. ReleaseBuffer

After the buffer population is complete, the producer calls the Queuebuffer method to join the buffer to the queue and notifies the consumer.

status_t BufferQueueProducer::queueBuffer(int slot,        const QueueBufferInput &input, QueueBufferOutput *output) {    .......        frameAvailableListener = mCore->mConsumerListener;        ......        frameAvailableListener->onFrameAvailable(item);        ......    }
    • Gets the member variable mconsumerlistener (consumer listener interface) within the Bufferqueuecore
    • Callback interface Method onframeavailable

So the question comes again, where is mconsumerlistener to set it?

status_t BufferQueueConsumer::connect(          const sp<IConsumerListener>& consumerListener, bool controlledByApp) {    ATRACE_CALL();                          if (consumerListener == NULL) {             BQ_LOGE("connect(C): consumerListener may not be NULL");        return BAD_VALUE;                   }    BQ_LOGV("connect(C): controlledByApp=%s",            controlledByApp ? "true" : "false");         Mutex::Autolock lock(mCore->mMutex);    if (mCore->mIsAbandoned) {        BQ_LOGE("connect(C): BufferQueue has been abandoned");        return NO_INIT;    }      mCore->mConsumerListener = consumerListener;    mCore->mConsumerControlledByApp = controlledByApp;    return NO_ERROR;}
    • The Consumerlistener interface pointer is passed into the Bufferqueueconsumer::connect function and set to Mcore->mconsumerlistener
    • And ultimately decide where to spend it. The interface object type passed in when the Bufferqueueconsumer interface calls the Connect function

Android Surfaceflinger Service (i)-----bufferqueue analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.