05 深入解析surfaceControl getSurface

前面我们使用surfaceComposerClient->createSurface创建了surfaceControl 《SurfaceFinger layer创建过程》;要想绘制图像还得创建Surface,我们可以使用SurfaceControl::getSurface()来创建Surface

getSurface实现

sp<Surface> SurfaceControl::getSurface()
{
    if (mSurfaceData == nullptr) {
        return generateSurfaceLocked();
    }
    return mSurfaceData;
}

mutable sp<Surface> mSurfaceData;

此函数的目的只有一个,获取mSurfaceData;而mSurfaceData是Surface。由于mSurfaceData不为空直接返回,则一个SurfaceControl里只会有一个Surface。第一次进入mSurfaceData肯定为空,会调用generateSurfaceLocked

创建Surface,构建BLASTBufferQueue

sp<Surface> SurfaceControl::generateSurfaceLocked()
{
    uint32_t ignore;
    auto flags = mCreateFlags & (ISurfaceComposerClient::eCursorWindow |
                                 ISurfaceComposerClient::eOpaque);
    mBbqChild = mClient->createSurface(String8("bbq-wrapper"), 0, 0, mFormat,
                                       flags, mHandle, {}, &ignore);
    mBbq = sp<BLASTBufferQueue>::make("bbq-adapter", mBbqChild, mWidth, mHeight, mFormat);

    mSurfaceData = mBbq->getSurface(true);

    return mSurfaceData;
}

主要作用:

  1. 再创建一个名为bbq-wrapper的SurfaceControl
  2. 使用创建的SurfaceControl,构建BLASTBufferQueue
  3. 通过构建的BLASTBufferQueue创建Surface。

通过SurfaceComposerClient::createSurface创建SurfaceControl的详细过程前面已经解析过了。《SurfaceFinger layer创建过程》

先看下BLASTBufferQueue的构造函数

BLASTBufferQueue的构造函数

  1. 创建生产者和消费者
  2. 将BLASTBufferQueue设置为FrameAvailableListener和BufferFreedListener;设置mBufferItemConsumer的其他属性
  3. 清空mNumAcquired,mNumFrameAvailable
BLASTBufferQueue::BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface,
                                   int width, int height, int32_t format)
      : mSurfaceControl(surface),
        mSize(width, height),
        mRequestedSize(mSize),
        mFormat(format),
        mNextTransaction(nullptr) {
    createBufferQueue(&mProducer, &mConsumer);


    mProducer->setMaxDequeuedBufferCount(2);
    mBufferItemConsumer = new BLASTBufferItemConsumer(mConsumer,
                                                      GraphicBuffer::USAGE_HW_COMPOSER |
                                                              GraphicBuffer::USAGE_HW_TEXTURE,
                                                      1, false);
    static int32_t id = 0;
    mName = name + "#" + std::to_string(id);
    auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
    mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
    id++;
    mBufferItemConsumer->setName(String8(consumerName.c_str()));
    mBufferItemConsumer->setFrameAvailableListener(this);
    mBufferItemConsumer->setBufferFreedListener(this);
    mBufferItemConsumer->setxxx();

    ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
    mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);

    mTransformHint = mSurfaceControl->getTransformHint();
    mBufferItemConsumer->setTransformHint(mTransformHint);
    SurfaceComposerClient::Transaction()
            .setFlags(surface, layer_state_t::eEnableBackpressure,
                      layer_state_t::eEnableBackpressure)
            .setApplyToken(mApplyToken)
            .apply();
    mNumAcquired = 0;
    mNumFrameAvailable = 0;
    BQA_LOGV("BLASTBufferQueue created width=%d height=%d format=%d mTransformHint=%d", width,
             height, format, mTransformHint);
}

BLASTBufferItemConsumer的构造函数

BLASTBufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
                            int bufferCount, bool controlledByApp)
          : BufferItemConsumer(consumer, consumerUsage, bufferCount, controlledByApp),
            mCurrentlyConnected(false),
            mPreviouslyConnected(false),
            mBLASTBufferQueue(nullptr) {}
            
BufferItemConsumer::BufferItemConsumer(
        const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
        int bufferCount, bool controlledByApp) :
    ConsumerBase(consumer, controlledByApp)

ConsumerBase的构造函数,创建listerner 调用BufferQueueConsumer的consumerConnect

android12\frameworks\native\libs\gui\ConsumerBase.cpp

ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
        mAbandoned(false),
        mConsumer(bufferQueue),
        mPrevFinalReleaseFence(Fence::NO_FENCE) {
    // Choose a name using the PID and a process-unique ID.
    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());

    wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
    sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);

    status_t err = mConsumer->consumerConnect(proxy, controlledByApp);

    mConsumer->setConsumerName(mName);
}

设置ConsumerListener

android12\frameworks\native\libs\gui\include\gui\BufferQueueConsumer.h
    virtual status_t consumerConnect(const sp<IConsumerListener>& consumer,
            bool controlledByApp) {
        return connect(consumer, controlledByApp);
    }
    
status_t BufferQueueConsumer::connect(
        const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
    mCore->mConsumerListener = consumerListener;
    mCore->mConsumerControlledByApp = controlledByApp;

}

再回去看下mBufferItemConsumer->setFrameAvailableListener(this);BLASTBufferItemConsumer一路继承,最后的子类是ConsumerBase,所以会调用ConsumerBase::setFrameAvailableListener

void ConsumerBase::setFrameAvailableListener(
        const wp<FrameAvailableListener>& listener) {
    mFrameAvailableListener = listener;
}

所有的东西都准备得差不多了,现在开始创建BBQSurface;

BBQSurface是给生产者使用,所以要传入生产者,还有surfaceflinger创建得layer得handle,然后对Surface的成员进行初始化等待;

这样只要拿到Surface就拿到了BLASTBufferQueue,拿到了生产者等等。内容不多,这里只贴下代码。

BLASTBufferQueue getSurface

sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
    sp<IBinder> scHandle = nullptr;
    if (includeSurfaceControlHandle && mSurfaceControl) {
        scHandle = mSurfaceControl->getHandle();
    }
    return new BBQSurface(mProducer, true, scHandle, this);  //scHandle 就是SurfaceControl里的mHandle
}

BBQSurface的构造函数

BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
           const sp<IBinder>& scHandle, const sp<BLASTBufferQueue>& bbq)
      : Surface(igbp, controlledByApp, scHandle), mBbq(bbq) {}
Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp,
                 const sp<IBinder>& surfaceControlHandle)
      : mGraphicBufferProducer(bufferProducer),
        mCrop(Rect::EMPTY_RECT),
        mBufferAge(0),
        mGenerationNumber(0),
        mSharedBufferMode(false),
        mAutoRefresh(false),
        mAutoPrerotation(false),
        mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
        mSharedBufferHasBeenQueued(false),
        mQueriedSupportedTimestamps(false),
        mFrameTimestampsSupportsPresent(false),
        mEnableFrameTimestamps(false),
        mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) {
    // Initialize the ANativeWindow function pointers.
    ANativeWindow::setSwapInterval  = hook_setSwapInterval;
    ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
    ANativeWindow::cancelBuffer     = hook_cancelBuffer;
    ANativeWindow::queueBuffer      = hook_queueBuffer;
    ANativeWindow::query            = hook_query;
    ANativeWindow::perform          = hook_perform;

    ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
    ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;
    ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;
    ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;

    const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;

    mReqWidth = 0;
    mReqHeight = 0;
    mReqFormat = 0;
    mReqUsage = 0;
    mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
    mDataSpace = Dataspace::UNKNOWN;
    mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
    mTransform = 0;
    mStickyTransform = 0;
    mDefaultWidth = 0;
    mDefaultHeight = 0;
    mUserWidth = 0;
    mUserHeight = 0;
    mTransformHint = 0;
    mConsumerRunningBehind = false;
    mConnectedToCpu = false;
    mProducerControlledByApp = controlledByApp;
    mSwapIntervalZero = false;
    mMaxBufferCount = NUM_BUFFER_SLOTS;
    mSurfaceControlHandle = surfaceControlHandle;
}

总结:

SurfaceControl::getSurface()返回的实际是BBQSurface,BBQSurface继承Surface,可以使用Surface表示。BBQSurface是对生产者,handle的封装,其中包含了对buffer的操作。并且本文对FrameAvailableListener的初始化进行了简要阐述,后面会聊到FrameAvailableListener的具体用处,敬请期待。

创造不易,欢迎点赞收藏。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值