Google Filament 渲染引擎(2)-Backend 核心类先容
阅读分析:
- 本文基于 filament 版本: v1.58.0
- 文本更加论述 Backend 内部核心类的关系, 示例代码作了非常多的删减和简化
文本将以创建纹理为例, 论述 Backend 内部的流程。后端图形接口以 OpenGL 为例。
核心类的功能概览:
- Dispatcher: 本质上只是一个函数指针的集合,用于将命令与驱动接口的方法绑定。在初始化阶段,这些函数指针就被填充好。
- Driver: 负责管理底层驱动的状态,以及与硬件交互的详细实现。
- CommandStream: 负责接收命令,并将其发送到驱动。
- Command: 命令对象,包含了详细的命令类型和参数, 负责命令的封装和执行.
- Engine: 负责管理资源的创建和烧毁,以及命令的提交。
一、底层驱动初始化
- // --------------------------------- step1: 创建 Driver ----------------------------------
- Backend mBackend = Backend::OPENGL;
- // 根据类型选择平台, 以 PlatformCocoaGL 为例
- PlatformCocoaGL platform = filament::backend::PlatformFactory::create(&mBackend);
- // 根据平台创建驱动, 这里 driver 的类型是 OpenGLDriver
- Driver* driver = platform->createDriver();
- // --------------------------------- step2: 创建 CommandStream ----------------------------------
- using DriverApi = filament::backend::CommandStream;
- // 这里完成 底层驱动 绑定到 CommandStream 的 Dispatcher 上
- DriverApi* driverApi = new DriverApi(*driver);
复制代码 二、创建纹理
应用层创建代码:
- filament::Texture* texture = Texture::Builder()
- .levels(1)
- .sampler(Texture::Sampler::SAMPLER_EXTERNAL)
- .build(*mEngine);
复制代码- Texture* Texture::Builder::build(Engine& engine) {
- // 调用 Engine 的 createTexture 方法
- return downcast(engine).createTexture(*this);
- }
复制代码 三、核心类
1、Engine
- // ====> 模板展开后的 createTexture 函数
- FTexture* FEngine::createTexture(const Texture::Builder& builder) noexcept {
- // 展开 create 模板调用
- FTexture* p = mHeapAllocator.make<FTexture>(*this, builder);
- if (p) {
- mTextures.insert(p);
- }
- return p;
- }
复制代码- FTexture::FTexture() {
- backend::Handle<backend::HwTexture> mHandle;
- // driver 的实际类型是 CommandStream
- FEngine::DriverApi& driver = engine.getDriverApi();
- mHandle = driver.createTexture(
- mTarget, mLevelCount, mFormat, mSampleCount, mWidth, mHeight, mDepth, mUsage);
- }
复制代码 2、CommandStream
- // 构造函数:
- CommandStream::CommandStream(Driver& driver, CircularBuffer& buffer) noexcept
- : mDriver(driver),
- mCurrentBuffer(buffer),
- mDispatcher(driver.getDispatcher())
- {
- }
复制代码- // 纹理创建函数
- inline backend::TextureHandle createTexture(
- backend::SamplerType target,
- uint8_t levels,
- backend::TextureFormat format,
- uint8_t samples,
- uint32_t width,
- uint32_t height,
- uint32_t depth,
- backend::TextureUsage usage) {
- // 分配结构体内存
- backend::TextureHandle result = this->mDriver.createTextureS();
- // 定义命令类型
- using Cmd = CommandType<decltype(&Driver::createTextureR)>::Command<&Driver::createTextureR>;
- // 分配命令缓冲区内存
- void* const p = this->allocateCommand(CommandBase::align(sizeof(Cmd)));
- // 在分配的内存上构造命令对象
- new (p) Cmd(
- // 真正需要执行的命令
- this->mDispatcher.createTexture_,
- backend::TextureHandle(result),
- std::move(target),
- std::move(levels),
- std::move(format),
- std::move(samples),
- std::move(width),
- std::move(height),
- std::move(depth),
- std::move(usage)
- );
- return result;
- }
复制代码 3、Command
- // 特化模板类 Command
- template<>
- class Command<&filament::backend::Driver::createTextureR> : public filament::backend::CommandBase {
- using SavedParameters = std::tuple<
- std::remove_reference_t<filament::backend::Handle<filament::backend::HwTexture>>,
- std::remove_reference_t<filament::backend::SamplerType>,
- std::remove_reference_t<unsigned char>,
- std::remove_reference_t<filament::backend::TextureFormat>,
- std::remove_reference_t<unsigned char>,
- std::remove_reference_t<unsigned int>,
- std::remove_reference_t<unsigned int>,
- std::remove_reference_t<unsigned int>,
- std::remove_reference_t<filament::backend::TextureUsage>
- >;
- SavedParameters mArgs;
- void log() noexcept;
- template <std::size_t ...I>
- void log(std::index_sequence<I...>) noexcept;
- public:
- template <typename M, typename D>
- static inline void execute(M &&method, D &&driver, filament::backend::CommandBase *base, intptr_t *next);
- inline Command(Command<&filament::backend::Driver::createTextureR> &&rhs) noexcept = default;
- template <typename ...A>
- inline constexpr explicit Command(filament::backend::Execute execute, A &&...args);
- template<>
- inline constexpr explicit Command<filament::backend::Handle<filament::backend::HwTexture>,
- filament::backend::SamplerType,
- unsigned char,
- filament::backend::TextureFormat,
- unsigned char,
- unsigned int,
- unsigned int,
- unsigned int,
- filament::backend::TextureUsage>(
- filament::backend::Execute execute,
- filament::backend::Handle<filament::backend::HwTexture> &&arg1,
- filament::backend::SamplerType &&arg2,
- unsigned char &&arg3,
- filament::backend::TextureFormat &&arg4,
- unsigned char &&arg5,
- unsigned int &&arg6,
- unsigned int &&arg7,
- unsigned int &&arg8,
- filament::backend::TextureUsage &&arg9
- ) : filament::backend::CommandBase(execute),
- mArgs(std::forward<filament::backend::Handle<filament::backend::HwTexture>>(arg1),
- std::forward<filament::backend::SamplerType>(arg2),
- std::forward<unsigned char>(arg3),
- std::forward<filament::backend::TextureFormat>(arg4),
- std::forward<unsigned char>(arg5),
- std::forward<unsigned int>(arg6),
- std::forward<unsigned int>(arg7),
- std::forward<unsigned int>(arg8),
- std::forward<filament::backend::TextureUsage>(arg9)) {
- }
- static inline void *operator new(std::size_t, void *ptr) {
- if (__builtin_expect(!(ptr), false)) {
- utils::panic(__func__, "root/filament/filament/backend/include/private/backend/CommandStream.h", 159, "ptr");
- }
- return ptr;
- }
- };
复制代码 4、Driver
1)命令的绑定
- Dispatcher OpenGLDriver::getDispatcher() const noexcept {
- auto dispatcher = ConcreteDispatcher<OpenGLDriver>::make();
- return dispatcher;
- }
复制代码 2)分配结构体内存
- struct GLTexture : public HwTexture {
- using HwTexture::HwTexture;
- struct GL {
- GL() noexcept : imported(false), external(false), sidecarSamples(1), reserved1(0) {}
- GLuint id = 0; // texture or renderbuffer id
- GLenum target = 0;
- GLenum internalFormat = 0;
- GLuint sidecarRenderBufferMS = 0; // multi-sample sidecar renderbuffer
- // texture parameters go here too
- GLfloat anisotropy = 1.0;
- int8_t baseLevel = 127;
- int8_t maxLevel = -1;
- uint8_t reserved0 = 0;
- bool imported : 1;
- bool external : 1;
- uint8_t sidecarSamples : 3;
- uint8_t reserved1 : 3;
- std::array<TextureSwizzle, 4> swizzle{
- TextureSwizzle::CHANNEL_0,
- TextureSwizzle::CHANNEL_1,
- TextureSwizzle::CHANNEL_2,
- TextureSwizzle::CHANNEL_3
- };
- } gl;
- mutable Handle<GLTextureRef> ref;
- OpenGLPlatform::ExternalTexture* externalTexture = nullptr;
- };
- // 分配内存并构造一个 filament::backend::GLTexture 对象
- template<> Handle<GLTexture> initHandle<filament::backend::GLTexture, <>>() {
- return this->mHandleAllocator.allocateAndConstruct<filament::backend::GLTexture>();
- }
- Handle<HwTexture> OpenGLDriver::createTextureS() noexcept {
- return this->initHandle<GLTexture>();
- }
复制代码 3)使用 OpenGL API 创建纹理
- void OpenGLDriver::createTextureR(Handle<HwTexture> th, SamplerType target, uint8_t levels,
- TextureFormat format, uint8_t samples, uint32_t w, uint32_t h, uint32_t depth,
- TextureUsage usage) {
- auto &gl = this->mContext;
- glTexStorage2D(t->gl.target, GLsizei(t->levels), t->gl.internalFormat, GLsizei(width), GLsizei(height));
- // ...
- }
复制代码 5、Dispatcher
- using Execute = void (*)(Driver& driver, CommandBase* self, intptr_t* next);
- Execute createTexture_;
复制代码- // 这里完成 底层驱动 绑定到 Dispatcher 上
- template <typename ConcreteDriver> class ConcreteDispatcher {
- static void createTexture(Driver &driver, CommandBase *base, intptr_t *next) {
- using Cmd = CommandType<decltype(&Driver::createTextureR)>::Command<&Driver::createTextureR>;
- ConcreteDriver &concreteDriver = static_cast<ConcreteDriver &>(driver);
- Cmd::execute(& ConcreteDriver::createTextureR, concreteDriver, base, next);
- }
- }
- template <typename ConcreteDriver> Dispatcher ConcreteDispatcher<ConcreteDriver>::make() {
- Dispatcher dispatcher;
- dispatcher.createTexture_ = &ConcreteDispatcher<T>::createTexture;
- // ...
- return dispatcher;
- }
复制代码 四、总结
这表明 Engine -> CommandStream -> Dispatcher 形成了调用链,每一层都负责不同的任务,Engine 负责 API 层接口,CommandStream 负责命令封装,Dispatcher 负责命令派发, Driver 负责最终执行。
五、辅助工具
1)Engine
命令出处:
cmake-build-debug/compile_commands.json
预处置惩罚命令:
- // root/filament:
- clang++ -E \
- -I../libs/filabridge/include \
- -I../third_party/robin-map \
- -I../libs/utils/include \
- -I../libs/filaflat/include \
- -I../libs/math/include \
- -I../cmake-build-debug/filament/ \
- -I./include \
- -I./backend/include \
- -I./src/details \
- -I./components \
- -I./src \
- ./src/details/Engine.cpp -o 123.cpp
复制代码 编译模板睁开:
- // root/filament:
- clang++ \
- -Xclang -ast-print -fsyntax-only -std=c++17 \
- root/filament/filament/src/Engine.cpp > record_layouts.txt 2>&1 \
- -Iroot/filament/filament/include \
- -Iroot/filament/cmake-build-debug/filament \
- -Iroot/filament/filament/src \
- -Iroot/filament/filament/backend/include \
- -Iroot/filament/libs/math/include \
- -Iroot/filament/libs/utils/include \
- -Iroot/filament/third_party/robin-map/tnt/.. \
- -Iroot/filament/libs/bluevk/include \
- -Iroot/filament/third_party/vkmemalloc/tnt/../include \
- -Iroot/filament/third_party/smol-v/tnt/../source \
- -Iroot/filament/libs/filaflat/include \
- -Iroot/filament/libs/filabridge/include \
- -Iroot/filament/libs/ibl/include \
- -Iroot/filament/libs/matdbg/include \
- -Iroot/filament/third_party/civetweb/tnt/../include \
- -Iroot/filament/libs/filamat/include \
- -Iroot/filament/cmake-build-debug/shaders \
- -Iroot/filament/cmake-build-debug/include \
- -Iroot/filament/third_party/glslang/glslang/tnt/../Include \
- -Iroot/filament/third_party/glslang/glslang/tnt/../Public \
- -Iroot/filament/third_party/glslang/glslang/tnt/../MachineIndependent \
- -Iroot/filament/third_party/glslang/glslang/tnt/../.. \
- -Iroot/filament/third_party/glslang/SPIRV/tnt/.. \
- -Iroot/filament/third_party/glslang/SPIRV/tnt/../.. \
- -Iroot/filament/third_party/spirv-tools/include \
- -Iroot/filament/third_party/spirv-headers/include \
- -Iroot/filament/third_party/spirv-cross/tnt/..
复制代码 2)CommandStream
预处置惩罚命令:
- // root/filament/backend:
- g++ -E -I../../libs/utils/include -I../../libs/math/include -I../include -I./include ./src/CommandStream.cpp -o CommandStream.i
复制代码 3)Driver
- clang++ \
- -Xclang -ast-print -fsyntax-only -std=c++17 \
- root/filament/backend/src/opengl/OpenGLDriver.cpp > record_layouts.txt 2>&1 \
- -Iroot/filament/include \
- -Iroot/cmake-build-debug/filament \
- -Iroot/filament/src \
- -Iroot/filament/backend/include \
- -Iroot/filament/backend/src \
- -Iroot/cmake-build-debug/filament/backend \
- -Iroot/libs/math/include \
- -Iroot/libs/utils/include \
- -Iroot/third_party/robin-map/tnt/.. \
- -Iroot/libs/bluegl/include \
- -Iroot/libs/bluevk/include \
- -Iroot/third_party/vkmemalloc/tnt/../include \
- -Iroot/third_party/smol-v/tnt/../source \
- -Iroot/third_party/spirv-headers/include
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |