SurfaceFlinger学习2

Layer

class Layer : public virtual RefBase, compositionengine::LayerFE {
    mutable bool contentDirty{false};
    Region surfaceDamageRegion;

    // Layer serial number.  This gives layers an explicit ordering, so we
    // have a stable sort order when their layer stack and Z-order are
    // the same.
    int32_t sequence{sSequence++};
        // constant
    sp<SurfaceFlinger> mFlinger;

    protected:
    compositionengine::OutputLayer* findOutputLayerForDisplay(const DisplayDevice*) const;//OutputLayer最后合成的layer
    
        // these are protected by an external lock (mStateLock)
    State mCurrentState;
        // These are only accessed by the main thread or the tracing thread.
    State mDrawingState;
    const wp<Client> mClientRef;//who? mClientRef(args.client),
    /*
        // constant
    sp<SurfaceFlinger> mFlinger;

    // protected by mLock
    DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;
    */
    
    // Child list about to be committed/used for editing.
    LayerVector mCurrentChildren{LayerVector::StateSet::Current};
    // Child list used for rendering.
    LayerVector mDrawingChildren{LayerVector::StateSet::Drawing};

    wp<Layer> mCurrentParent;
    wp<Layer> mDrawingParent;
virtual bool isOpaque(const Layer::State&) const { return false; }
bool isSecure() const;
virtual bool isVisible() const = 0;
virtual bool isProtected() const { return false; }
virtual bool canReceiveInput() const;
bool isHiddenByPolicy() const;
    /*
     * doTransaction - process the transaction. This is a good place to figure
     * out which attributes of the surface have changed.
     */
    uint32_t doTransaction(uint32_t transactionFlags);

    /*
     * latchBuffer - called each time the screen is redrawn and returns whether
     * the visible regions need to be recomputed (this is a fairly heavy
     * operation, so this should be set only if needed). Typically this is used
     * to figure out if the content or size of a surface has changed.
     */
    virtual bool latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
                             nsecs_t /*expectedPresentTime*/) {
        return false;
    }

    virtual bool isBufferLatched() const { return false; }

    virtual void latchAndReleaseBuffer() {}
bool Layer::attachChildren() {
    bool changed = false;
    for (const sp<Layer>& child : mCurrentChildren) {
        sp<Client> parentClient = mClientRef.promote();
        sp<Client> client(child->mClientRef.promote());//class Client : public BnSurfaceComposerClient
        if (client != nullptr && parentClient != client) {
            if (child->mLayerDetached) {
                child->mLayerDetached = false;
                changed = true;
            }
            changed |= child->attachChildren();
        }
    }

    return changed;
}

BufferLayer

class BufferLayer : public Layer {
    
        bool latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
                     nsecs_t expectedPresentTime) override;

    bool isBufferLatched() const override { return mRefreshPending; }//override显示指明需要重写的方法

    BufferInfo mBufferInfo;

BufferLayerConsumer

BufferLayerConsumer consumes buffers of graphics data from a BufferQueue,
and makes them available to RenderEngine as a texture.
class BufferLayerConsumer : public ConsumerBase {
  
        // mCurrentTextureBuffer is the buffer containing the current texture. It's
    // possible that this buffer is not associated with any buffer slot, so we
    // must track it separately in order to support the getCurrentBuffer method.
    std::shared_ptr<Image> mCurrentTextureBuffer;
        // mCurrentCrop is the crop rectangle that applies to the current texture.
    // It gets set each time updateTexImage is called.
    Rect mCurrentCrop;
        // The portion of this surface that has changed since the previous frame
    Region mCurrentSurfaceDamage;
    
        // Utility class for managing GraphicBuffer references into renderengine
    class Image {
    public:
        Image(const sp<GraphicBuffer>& graphicBuffer, renderengine::RenderEngine& engine);
        virtual ~Image();
        const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; }

    private:
        // mGraphicBuffer is the buffer that was used to create this image.
        sp<GraphicBuffer> mGraphicBuffer;
        // Back-reference into renderengine to initiate cleanup.
        renderengine::RenderEngine& mRE;
        DISALLOW_COPY_AND_ASSIGN(Image);
    };

BufferQueueLayer

/*
 * A new BufferQueue and a new BufferLayerConsumer are created when the
 * BufferLayer is first referenced.
 *
 * This also implements onFrameAvailable(), which notifies SurfaceFlinger
 * that new data has arrived.
 */
class BufferQueueLayer : public BufferLayer {
class BufferStateLayer : public BufferLayer {//Interface implementation for Layer
    sp<BufferLayerConsumer> mConsumer;
    sp<IGraphicBufferProducer> mProducer;
    
    Vector<BufferItem> mQueueItems;
    sp<ContentsChangedListener> mContentsChangedListener;
    // -----------------------------------------------------------------------
    // Interface implementation for BufferLayerConsumer::ContentsChangedListener
    // -----------------------------------------------------------------------
    class ContentsChangedListener : public BufferLayerConsumer::ContentsChangedListener {
    public:
        ContentsChangedListener(BufferQueueLayer* bufferQueueLayer)
              : mBufferQueueLayer(bufferQueueLayer) {}
        void abandon();

    protected:
        void onFrameAvailable(const BufferItem& item) override;
        void onFrameReplaced(const BufferItem& item) override;
        void onSidebandStreamChanged() override;
        void onFrameDequeued(const uint64_t bufferId) override;
        void onFrameDetached(const uint64_t bufferId) override;
        void onFrameCancelled(const uint64_t bufferId) override;

    private:
        BufferQueueLayer* mBufferQueueLayer = nullptr;
        Mutex mMutex;
    };

Client

SurfaceComposerClient服务的本地Binder实现

class Client : public BnSurfaceComposerClient
    
        // constant
    sp<SurfaceFlinger> mFlinger;

    // protected by mLock
    DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayers;

从return mFlinger->createLayer可知,Client是暴露给producer的接口,Client又是一个转接类,真正的实现,由mFlinger完成

Client属于匿名binder服务,外界的进程不可能直接获取到,因而首先需要借助SurfaceFlinger这一实名binder Service

sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
    const sp<Client> client = new Client(this);
    return client->initCheck() == NO_ERROR ? client : nullptr;
}
Client::Client(const sp<SurfaceFlinger>& flinger)
    : mFlinger(flinger)
{
}

sp<Layer> Client::getLayerUser(const sp<IBinder>& handle) const
{
    Mutex::Autolock _l(mLock);
    sp<Layer> lbc;
    wp<Layer> layer(mLayers.valueFor(handle));
    if (layer != 0) {
        lbc = layer.promote();
        ALOGE_IF(lbc==0, "getLayerUser(name=%p) is dead", handle.get());
    }
    return lbc;
}

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

MonitoredProducer

// MonitoredProducer wraps an IGraphicBufferProducer so that SurfaceFlinger will
// be notified upon its destruction
class MonitoredProducer : public BnGraphicBufferProducer {
    public:
    MonitoredProducer(const sp<IGraphicBufferProducer>& producer,
            const sp<SurfaceFlinger>& flinger,
            const wp<Layer>& layer);
        // The Layer which created this producer, and on which queued Buffer's will be displayed.
    sp<Layer> getLayer() const;
private:
    sp<IGraphicBufferProducer> mProducer;
    sp<SurfaceFlinger> mFlinger;
    // The Layer which created this producer, and on which queued Buffer's will be displayed.
    wp<Layer> mLayer;
};

MonitoredProducerde 功能与Client差不多

status_t MonitoredProducer::dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w, uint32_t h,
                                          PixelFormat format, uint64_t usage,
                                          uint64_t* outBufferAge,
                                          FrameEventHistoryDelta* outTimestamps) {
    return mProducer->dequeueBuffer(slot, fence, w, h, format, usage, outBufferAge, outTimestamps);
}

LayerVector

/*
 * Used by the top-level SurfaceFlinger state and individual layers
 * to track layers they own sorted according to Z-order. Provides traversal
 * functions for traversing all owned layers, and their descendents.
 */
class LayerVector : public SortedVector<sp<Layer>> {
public:
    enum class StateSet {
        Invalid,
        Current,
        Drawing,
    };
    
private:
    const StateSet mStateSet;

ComposerService

class ComposerService : public Singleton<ComposerService>
{
    sp<ISurfaceComposer> mComposerService;
    sp<IBinder::DeathRecipient> mDeathObserver;
    Mutex mLock;

    ComposerService();
    void connectLocked();
    void composerServiceDied();
    friend class Singleton<ComposerService>;
public:

    // Get a connection to the Composer Service.  This will block until
    // a connection is established.
    static sp<ISurfaceComposer> getComposerService();//得到SurfaceFlinger的Binder代理对象

};
sp<ISurfaceComposer> composer;
composer = ComposerService::getComposerService();
或者 getService("SurfaceFlinger", &composer);

ISurfaceComposerClient,得到SurfaceComposerClient的Binder代理对象,ISurfaceComposerClient is the interface to create Surface。

sp<ISurfaceComposerClient> composerClient = composer->createConnection();

要操作Surface,需要得到SurfaceControl

sp<SurfaceControl> surfaceControl = composerClient->createSurface();

int Surface::lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);//得到一块surface(Layer)
int Surface::unlockAndPost();
all-kinds-of-buffers.png

SurfaceFlinger

SurfaceFlinger实现了ISurfaceComposer接口,是服务端

参考资料:https://waynewolf.github.io/2014/06/22/surfaceflinger-and-client/

class SurfaceFlinger : public BnSurfaceComposer,
                       public PriorityDumper,
                       public ClientCache::ErasedRecipient,
                       private IBinder::DeathRecipient,
                       private HWC2::ComposerCallback,
                       private ISchedulerCallback {
status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override;
     /* ISurfaceComposer interface
     */
    sp<ISurfaceComposerClient> createConnection() override;
handleMessageRefresh
     |—> preComposition
     |—> rebuildLayerStacks
     |—> setUpHWComposer
          |—> HWComposer::createWorkList <== hwc="" structures="" are="" allocated="" |—=""> Layer::setGeometry()
          |—  set per frame data
          |—  HWComposer::prepare
               |—> hwc prepare
     |—> doComposition
          |---- skip composition on external display if condition meets
          |—> doDisplayComposition
          |    |—> doComposeSurfaces
          |     |—> DisplayDevice::swapBuffers
          |          |—> eglSwapBuffers
          |          |—> FramebufferSurface::advanceFrame
          |—> DisplayDevice::flip(…)     <== just="" update="" statistics="" count="" |--=""> Call DisplayDevice::compositionComplete(), notify each display
               |--> DisplaySurface::compositionComplete()
                    |--> FramebufferSurface::compositionComplete()
                         |--> HWComposer::fbCompositionComplete()
                              |--> NoOP if HWC >= 1.1
                              |--> used only in framebuffer device case.
          |—> postFrameBuffer
               |—> HWComposer::commit
                    |—> hwc set
                    |—> update retireFenceFd of hwc_display_contents_1
               |—> DisplayDevice::onSwapBuffersCompleted
                    |—> FramebufferSurface::onFrameComitted
               |—> Layer::onLayerDisplayed
               |—   update some statistics
     |—> postCom

CompositionRefreshArgs

/**
 * A parameter object for refreshing a set of outputs
 */
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;

    // If true, forces the entire display to be considered dirty and repainted
    bool repaintEverything{false};
/**
 * An output layer contains the output-dependent composition state for a layer
 */
class OutputLayer {
    
/**
 * Encapsulates all the state involved with composing layers for an output
 */
class Output {
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354

推荐阅读更多精彩内容