美文网首页
Android 图形系统(9)---- 硬件合成HWC和Disp

Android 图形系统(9)---- 硬件合成HWC和Disp

作者: 特立独行的佩奇 | 来源:发表于2023-04-07 21:15 被阅读0次

本文重点介绍 SurfaceFlinger 和 Composer Service 的衔接流程

HWComposer.jpg

HWC2 Composer 的创建

SurfaceFlinger init 函数中,实例化了Hwc2::impl::Composer对象并且将其作为参数构造了 HWComposer 对象

void SurfaceFlinger::init() {
    ...
    getBE().mHwc.reset(
            new HWComposer(std::make_unique<Hwc2::impl::Composer>(getBE().mHwcServiceName)));
    getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
    ...
}

HWComposer 类中包含了重要对象:
std::unique_ptr<HWC2::Device> mHwcDevice;
std::vector<DisplayData> mDisplayData{HWC_NUM_PHYSICAL_DISPLAY_TYPES};

mHwcDevice 是 HWComposer的重要成员,在构造函数的初始化参数列表中实例化:

HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer)
      : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}

HWC2.cpp 中包含了 HWC2::Device,HWC2::Composer,HWC2::Display 三个重要类,HWC2::Device和HWC2::Composer 都只实例化一次,但是 HWC2::Display 可能有多个实例,对应于 primary,external,virtual 多个Display 对象

HWC2::Device 类型的mHwcDevice对象包含了 android::Hwc2::Composer 类型的mComposer对象,android::Hwc2::Composer是一个抽象基类,定义了调用到了Composer HAL Service 的基本接口,SurfaceFlinger 中会实例化的Hwc2::impl::Composer 就继承自android::Hwc2::Composer
Hwc2::impl::Composer 和 android::Hwc2::Composer都定义在 ComposerHal.cpp 中
android::Hwc2::Composer 是一个抽象类,基本接口定义如下:

class Composer {
public:
    virtual Error getReleaseFences(Display display, std::vector<Layer>* outLayers,
                                   std::vector<int>* outReleaseFences) = 0;

    virtual Error presentDisplay(Display display, int* outPresentFence) = 0;

    virtual Error setActiveConfig(Display display, Config config) = 0;

    /*
     * The composer caches client targets internally.  When target is nullptr,
     * the composer uses slot to look up the client target from its cache.
     * When target is not nullptr, the cache is updated with the new target.
     */
    virtual Error setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target,
                                  int acquireFence, Dataspace dataspace,
                                  const std::vector<IComposerClient::Rect>& damage) = 0;
}

Hwc2::impl::Composer 中继承实现了这些接口,在这些接口中,创建了Composer HAL Service 的client 端,开始和Composer HAL Service 通信

Composer::Composer(const std::string& serviceName) : mWriter(kWriterInitialSize),
      mIsUsingVrComposer(serviceName == std::string("vr"))
{
    ......
    mComposer = V2_1::IComposer::getService(serviceName);

    if (mComposer == nullptr) {
        LOG_ALWAYS_FATAL("failed to get hwcomposer service");
    }

    mComposer->createClient(
            [&](const auto& tmpError, const auto& tmpClient)
            {
                if (tmpError == Error::NONE) {
                    mClient = tmpClient;
                }

}

registerCallback 和 HWC2::Display 对象创建

Composer Service 中提供了registerCallback接口,将函数通过registerCallback注册到 Composer HAL Service,ComposerService 会在Vsync,HotPlug 和 Refresh 事件发生时执行:
registerCallback 提供的接口如下:
HWC2.h

class ComposerCallback {
 public:
    virtual void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
                                   Connection connection) = 0;
    virtual void onRefreshReceived(int32_t sequenceId,
                                   hwc2_display_t display) = 0;
    virtual void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
                                 int64_t timestamp) = 0;
    virtual ~ComposerCallback() = default;
};

SurfaceFlinger 在init 中,将 this 指针也就是本身注册到了 HWComposer 中,HWComposer 经过mHwcDevice传递到最终是在 HWC2::Device 中实际注册,中间有一个 ComposerCallbackBridge对象的传递,SurfaceFlinger 继承了 HWC::ComposerCallback 类,因此 CallBack 的回调函数实现是在 SurfaceFlinger 中

SurfaceFlinger 中还是会转到 HWComposer 类中做处理,HWComposer 在转回到HWC:Device 中处理,HWC:Device的onHotplug 函数中,会判断Display 的ID 和 Connected 状态是 Connected 还是 Disconnected,创建相应的 Display 对象,保存在std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays;

void Device::onHotplug(hwc2_display_t displayId, Connection connection) {
        auto newDisplay = std::make_unique<Display>(
                *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, displayType);
        newDisplay->setConnected(true);
        mDisplays.emplace(displayId, std::move(newDisplay));
}

注意创建 newDisplay的参数中,将*mComposer.get() 传递了过去,也就是将HWC2::Composer 对象传递了过去保存为 mComposer 成员
这样 HWC2:Display 中 就可以通过mComposer 直接和 ComposerService 进行交互,对于其中 createLayer等接口,返回的 Layer 也有相应的 类HWC::Layer作为一层抽象
HWC2::device 中包含了mDisplays 对象,根据DisplayID 区分,表示可以支持多个Display
std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays;
此时:
Primary Display,External Display 和 Virtual Display 都可以通过 HWC:Display 实例和 Composer HAL Service 交互

DisplayData

DisplayData 类用于保存 HWC2:Display 和 Composer HAL service 交互时的信息

struct DisplayData {
    DisplayData();
    ~DisplayData();
    void reset();

    bool hasClientComposition;
    bool hasDeviceComposition;
    HWC2::Display* hwcDisplay; // 实际创建的 Display 对象
    HWC2::DisplayRequest displayRequests;
    sp<Fence> lastPresentFence;  // signals when the last set op retires
    std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
    buffer_handle_t outbufHandle;
    sp<Fence> outbufAcquireFence;
    mutable std::unordered_map<int32_t,
            std::shared_ptr<const HWC2::Display::Config>> configMap;

    // protected by mVsyncLock
    HWC2::Vsync vsyncEnabled;

    bool validateWasSkipped;
    HWC2::Error presentError;
};

HWC2::Display* hwcDisplay 保存了HotPlug 处理中创建的 Display 对象,可以直接和Display 对象交互

DisplayDevice

DisplayDevice 是显示设备的抽象,Android 定义了下面三种类型的显示设备:

  • Display Primary: 主显示设备,通常是LCD 显示屏
  • Display External: 扩展显示设备,可以通过 HDMI输出显示内容
  • Display Virtual: 虚拟显示设备,可以通过wifi 等输出画面
    SurfaceFlinger 中 DisplayDevice 负责和 OpenGL-ES 进行交互,SurfaceFlinger 需要将显示的图层设置到HWComposer 对象中,DisplayDevice 与 RenderEngine 交互,通过构造RE::Surface 的方式,使用 GLES RenderEngine 进行合成

DisplayDevice Create 和 prepareFrame 流程:


DisplayDevice.jpg

DisplayDevice 中的重要成员:

Vector< sp<Layer> > mVisibleLayersSortedByZ;  //当前需要显示的所有 Layer 实例
sp<ANativeWindow> mNativeWindow; // Surface 的实例,用于表示用于显示的 Surface
DisplayDevice 的创建
void SurfaceFlinger::processDisplayChangesLocked() {
        for (size_t i = 0; i < cc; i++) {
            sp<DisplaySurface> dispSurface;
            sp<IGraphicBufferProducer> producer;
            sp<IGraphicBufferProducer> bqProducer;
            sp<IGraphicBufferConsumer> bqConsumer;
            mCreateBufferQueue(&bqProducer, &bqConsumer, false);

            ......
            hwcId = state.type;
            dispSurface = new FramebufferSurface(*getBE().mHwc, hwcId, bqConsumer);
            producer = bqProducer;
        }
        
        if (dispSurface != nullptr) {
        mDisplays.add(display, setupNewDisplayDeviceInternal(display, hwcId, state, dispSurface, producer));
        if (!state.isVirtualDisplay()) {
            mEventThread->onHotplugReceived(state.type, true);
        }
        }
                
}

mCreateBufferQueue 是BufferQueue.h 中 createBufferQueue 函数的封装,功能是创建一个Bufferqueue
为Primary Display创建了一个 FramebufferSurface,如果是VirtualDisplay 则会创建 VirtualDisplaySurface;
以FramebufferSurface 作为参数,创建 DisplayDevice,逻辑在 setupNewDisplayDeviceInternal 函数中:

sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
        const wp<IBinder>& display, int hwcId, const DisplayDeviceState& state,
        const sp<DisplaySurface>& dispSurface, const sp<IGraphicBufferProducer>& producer) {
     
    auto nativeWindowSurface = mCreateNativeWindowSurface(producer);
    auto nativeWindow = nativeWindowSurface->getNativeWindow();

    ....

    const int displayInstallOrientation = state.type == DisplayDevice::DISPLAY_PRIMARY ?
        primaryDisplayOrientation : DisplayState::eOrientationDefault;

    // virtual displays are always considered enabled
    auto initialPowerMode = (state.type >= DisplayDevice::DISPLAY_VIRTUAL) ? HWC_POWER_MODE_NORMAL
                                                                           : HWC_POWER_MODE_OFF;

    sp<DisplayDevice> hw =
            new DisplayDevice(this, state.type, hwcId, state.isSecure, display, nativeWindow,
                              dispSurface, std::move(renderSurface), displayWidth, displayHeight,
                              displayInstallOrientation, hasWideColorGamut, hdrCapabilities,
                              supportedPerFrameMetadata, hwcColorModes, initialPowerMode);

}

以传入的Buffqueue producer构造nativeWindowSurface 和 nativeWindow 作为生产者端的 Surface,FramebufferSurface 继承 ConsumerBase 作为消费者端

Framebuffer 的合成

DisplayDevice 调用 swapBuffers,通知 RenderEngine 进行合成,RenderEngine 合成完成后,通过advanceFrame->nextBuffer获取图像数据,然后调用 HWComposer 的 setClientTarget 将FrameBuffer 数据传递给 Composer HAL Service

status_t FramebufferSurface::advanceFrame() {
    uint32_t slot = 0;
    sp<GraphicBuffer> buf;
    sp<Fence> acquireFence(Fence::NO_FENCE);
    Dataspace dataspace = Dataspace::UNKNOWN;
    status_t result = nextBuffer(slot, buf, acquireFence, dataspace);
    mDataSpace = dataspace;
    if (result != NO_ERROR) {
        ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
                strerror(-result), result);
    }
    return result;
}
Framebuffer 的显示

Surfacflinger 的postFramebuffer中,会调用HWComposer 的presentAndGetReleaseFences,通知Composer HAL service 显示所有的 ClientTarget 和 Device Layer

void SurfaceFlinger::postFramebuffer()
    const auto hwcId = displayDevice->getHwcDisplayId();
    if (hwcId >= 0) {
        getBE().mHwc->presentAndGetReleaseFences(hwcId);
    }

}
Frame_present.jpg

相关文章

网友评论

      本文标题:Android 图形系统(9)---- 硬件合成HWC和Disp

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