Repository: google/filament
File: filament/backend/src/webgpu/WebGPUSwapChain.h (C/C++)

Code before:

    void present();

private:

    void setExtent(wgpu::Extent2D const&);

    wgpu::Device mDevice = nullptr;
    enum class SwapChainType {
        HEADLESS,
        SURFACE
    };

    wgpu::Surface mSurface = {};
    wgpu::SurfaceConfiguration mConfig = {};
    bool mNeedStencil = false;
    wgpu::TextureFormat mDepthFormat = wgpu::TextureFormat::Undefined;
    wgpu::Texture mDepthTexture = nullptr;
    wgpu::TextureView mDepthTextureView = nullptr;
    const SwapChainType mType;
    const uint32_t mHeadlessWidth;
    const uint32_t mHeadlessHeight;

    ///TODO: eventually config for double or triple buffering
    static constexpr uint32_t mHeadlessBufferCount = 3;
    uint32_t mHeadlessBufferIndex = 0;
    std::array<wgpu::Texture, 3> mRenderTargetTextures;
    std::array<wgpu::TextureView, 3> mRenderTargetViews;
};

} // namespace filament::backend

#endif //TNT_FILAMENT_BACKEND_WEBGPUSWAPCHAIN_H


Review comment (bug):
Just knowledge sharing / context / C++-isms _(again, if you did not know)_... This is fine, but it might be helpful to have some extra context on indices, sizes, etc. in C++, something touched on in https://www.learncpp.com/cpp-tutorial/stdvector-and-the-unsigned-length-and-subscript-problem/ _"As Bjarne Stroustrup recalls, when the container classes in the C++ standard library was being designed (circa 1997), the designers had to choose whether to make the length (and array subscripts) signed or unsigned. They chose to make them unsigned."_ ... _"In retrospect, this is generally regarded as having been the wrong choice..."_ and https://www.learncpp.com/cpp-tutorial/arrays-loops-and-sign-challenge-solutions/. There are a lot of different approaches for a more safe and correct approach to these problems, but they all have their own down sides; unfortunately, there is not to my knowledge a clear best answer _(at least without a lot of verbosity in the code)_. Personally, I just end up using `size_t` in loops, but this can potentially be problematic too. (also more details on size_t in learncpp.com/cpp-tutorial/fixed-width-integers-and-size-t/ ). So, what you have here is fine, but just be aware this is a thorny thing in C++. This is yet another of many reasons to prefer algorithms when you can _(`#include <algorithm>`)_!

That said, I think a uint8_t would probably be fine here... the number of buffers should be small. Again, not an issue really, just something to consider.

Code after:

    void present();

private:

    void setExtent(wgpu::Extent2D const&);

    wgpu::Device mDevice = nullptr;
    enum class SwapChainType {
        HEADLESS,
        SURFACE
    };

    wgpu::Surface mSurface = {};
    wgpu::SurfaceConfiguration mConfig = {};
    bool mNeedStencil = false;
    wgpu::TextureFormat mDepthFormat = wgpu::TextureFormat::Undefined;
    wgpu::Texture mDepthTexture = nullptr;
    wgpu::TextureView mDepthTextureView = nullptr;
    const SwapChainType mType;
    const uint32_t mHeadlessWidth;
    const uint32_t mHeadlessHeight;

    static constexpr uint32_t mHeadlessBufferCount = 3;
    uint8_t mHeadlessBufferIndex = 0;
    std::array<wgpu::Texture, mHeadlessBufferCount> mRenderTargetTextures;
    std::array<wgpu::TextureView, mHeadlessBufferCount> mRenderTargetViews;
};

} // namespace filament::backend

#endif //TNT_FILAMENT_BACKEND_WEBGPUSWAPCHAIN_H