/*
 * Copyright 2023 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef skgpu_graphite_YUVATextureProxies_DEFINED
#define skgpu_graphite_YUVATextureProxies_DEFINED

#include "include/core/SkSpan.h"
#include "include/core/SkYUVAInfo.h"
#include "src/core/SkYUVAInfoLocation.h"
#include "src/gpu/graphite/TextureProxyView.h"

namespace skgpu::graphite {

class YUVATextureProxies {
public:
    YUVATextureProxies() = default;

    /** Assumes all planes are sampled with a default "rgba" swizzle. */
    YUVATextureProxies(const Recorder*,
                       const SkYUVAInfo&,
                       SkSpan<sk_sp<TextureProxy>>);
    /**
     * When uploading pixmaps to textures it is important that we account for how the original
     * pixmaps' channels are swizzled into the texture during upload. This will compute a swizzle
     * for each texture based on the original color types and the views' swizzles.
     */
    YUVATextureProxies(const Recorder*,
                       const SkYUVAInfo&,
                       SkSpan<TextureProxyView>);

    YUVATextureProxies(const YUVATextureProxies&) = default;
    YUVATextureProxies(YUVATextureProxies&&) = default;

    YUVATextureProxies& operator=(const YUVATextureProxies&) = default;
    YUVATextureProxies& operator=(YUVATextureProxies&&) = default;

    const SkYUVAInfo& yuvaInfo() const { return fYUVAInfo; }

    int numPlanes() const { return fYUVAInfo.numPlanes(); }

    // Overall set of YUVA proxies is mip mapped if each plane is mip mapped.
    Mipmapped mipmapped() const { return fMipmapped; }

    TextureProxy* proxy(int i) const { return fProxies[i].get(); }

    SkSpan<const sk_sp<TextureProxy>> proxies() const {
        return SkSpan<const sk_sp<TextureProxy>>(fProxies);
    }

    sk_sp<TextureProxy> refProxy(int i) const { return fProxies[i]; }

    TextureProxyView makeView(int i) const {
        return {fProxies[i], skgpu::Swizzle::RGBA()};
    }

    bool isValid() const { return fYUVAInfo.isValid(); }

    const SkYUVAInfo::YUVALocations& yuvaLocations() const { return fYUVALocations; }

private:
    std::array<sk_sp<TextureProxy>, SkYUVAInfo::kMaxPlanes> fProxies;
    SkYUVAInfo fYUVAInfo;
    Mipmapped fMipmapped = Mipmapped::kNo;
    SkYUVAInfo::YUVALocations fYUVALocations = {};
};

}  // namespace skgpu::graphite

#endif // skgpu_graphite_Image_YUVA_DEFINED
