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

#ifndef GrYUVABackendTextures_DEFINED
#define GrYUVABackendTextures_DEFINED

#include "include/core/SkTypes.h"
#include "include/core/SkYUVAInfo.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/ganesh/GrBackendSurface.h"
#include "include/gpu/ganesh/GrTypes.h"

#include <array>
#include <cstddef>

enum SkYUVColorSpace : int;

/**
 * A description of a set GrBackendTextures that hold the planar data described by a SkYUVAInfo.
 */
class SK_API GrYUVABackendTextureInfo {
public:
    static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;

    /** Default GrYUVABackendTextureInfo is invalid. */
    GrYUVABackendTextureInfo() = default;

    /**
     * Initializes a GrYUVABackendTextureInfo to describe a set of textures that can store the
     * planes indicated by the SkYUVAInfo. The texture dimensions are taken from the SkYUVAInfo's
     * plane dimensions. All the described textures share a common origin. The planar image this
     * describes will be mip mapped if all the textures are individually mip mapped as indicated
     * by skgpu::Mipmapped. This will produce an invalid result (return false from isValid()) if the
     * passed formats' channels don't agree with SkYUVAInfo.
     */
    GrYUVABackendTextureInfo(const SkYUVAInfo&,
                             const GrBackendFormat[kMaxPlanes],
                             skgpu::Mipmapped,
                             GrSurfaceOrigin);

    GrYUVABackendTextureInfo(const GrYUVABackendTextureInfo&) = default;

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

    bool operator==(const GrYUVABackendTextureInfo&) const;
    bool operator!=(const GrYUVABackendTextureInfo& that) const { return !(*this == that); }

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

    SkYUVColorSpace yuvColorSpace() const { return fYUVAInfo.yuvColorSpace(); }

    skgpu::Mipmapped mipmapped() const { return fMipmapped; }

    GrSurfaceOrigin textureOrigin() const { return fTextureOrigin; }

    /** The number of SkPixmap planes, 0 if this GrYUVABackendTextureInfo is invalid. */
    int numPlanes() const { return fYUVAInfo.numPlanes(); }

    /** Format of the ith plane, or invalid format if i >= numPlanes() */
    const GrBackendFormat& planeFormat(int i) const { return fPlaneFormats[i]; }

    /**
     * Returns true if this has been configured with a valid SkYUVAInfo with compatible texture
     * formats.
     */
    bool isValid() const { return fYUVAInfo.isValid(); }

    /**
     * Computes a YUVALocations representation of the planar layout. The result is guaranteed to be
     * valid if this->isValid().
     */
    SkYUVAInfo::YUVALocations toYUVALocations() const;

private:
    SkYUVAInfo fYUVAInfo;
    GrBackendFormat fPlaneFormats[kMaxPlanes];
    skgpu::Mipmapped fMipmapped = skgpu::Mipmapped::kNo;
    GrSurfaceOrigin fTextureOrigin = kTopLeft_GrSurfaceOrigin;
};

/**
 * A set of GrBackendTextures that hold the planar data for an image described a SkYUVAInfo.
 */
class SK_API GrYUVABackendTextures {
public:
    GrYUVABackendTextures() = default;
    GrYUVABackendTextures(const GrYUVABackendTextures&) = delete;
    GrYUVABackendTextures(GrYUVABackendTextures&&) = default;

    GrYUVABackendTextures& operator=(const GrYUVABackendTextures&) = delete;
    GrYUVABackendTextures& operator=(GrYUVABackendTextures&&) = default;

    GrYUVABackendTextures(const SkYUVAInfo&,
                          const GrBackendTexture[SkYUVAInfo::kMaxPlanes],
                          GrSurfaceOrigin textureOrigin);

    const std::array<GrBackendTexture, SkYUVAInfo::kMaxPlanes>& textures() const {
        return fTextures;
    }

    GrBackendTexture texture(int i) const {
        SkASSERT(i >= 0 && i < SkYUVAInfo::kMaxPlanes);
        return fTextures[static_cast<size_t>(i)];
    }

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

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

    GrSurfaceOrigin textureOrigin() const { return fTextureOrigin; }

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

    /**
     * Computes a YUVALocations representation of the planar layout. The result is guaranteed to be
     * valid if this->isValid().
     */
    SkYUVAInfo::YUVALocations toYUVALocations() const;

private:
    SkYUVAInfo fYUVAInfo;
    std::array<GrBackendTexture, SkYUVAInfo::kMaxPlanes> fTextures;
    GrSurfaceOrigin fTextureOrigin = kTopLeft_GrSurfaceOrigin;
};

#endif
