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

#ifndef GrTypesPriv_DEFINED
#define GrTypesPriv_DEFINED

#include <chrono>
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkPath.h"
#include "include/core/SkRefCnt.h"
#include "include/gpu/GrTypes.h"
#include "include/private/GrSharedEnums.h"
#include "include/private/SkImageInfoPriv.h"
#include "include/private/SkWeakRefCnt.h"

class GrBackendFormat;
class GrCaps;

// The old libstdc++ uses the draft name "monotonic_clock" rather than "steady_clock". This might
// not actually be monotonic, depending on how libstdc++ was built. However, this is only currently
// used for idle resource purging so it shouldn't cause a correctness problem.
#if defined(__GLIBCXX__) && (__GLIBCXX__ < 20130000)
using GrStdSteadyClock = std::chrono::monotonic_clock;
#else
using GrStdSteadyClock = std::chrono::steady_clock;
#endif

/**
 *  divide, rounding up
 */

static inline constexpr size_t GrSizeDivRoundUp(size_t x, size_t y) { return (x + (y - 1)) / y; }

/**
 *  align up to a power of 2
 */
static inline constexpr size_t GrAlignTo(size_t x, size_t alignment) {
    SkASSERT(alignment && SkIsPow2(alignment));
    return (x + alignment - 1) & ~(alignment - 1);
}

/**
 * Geometric primitives used for drawing.
 */
enum class GrPrimitiveType : uint8_t {
    kTriangles,
    kTriangleStrip,
    kPoints,
    kLines,          // 1 pix wide only
    kLineStrip,      // 1 pix wide only
    kPatches,
    kPath
};
static constexpr int kNumGrPrimitiveTypes = (int)GrPrimitiveType::kPath + 1;

static constexpr bool GrIsPrimTypeLines(GrPrimitiveType type) {
    return GrPrimitiveType::kLines == type || GrPrimitiveType::kLineStrip == type;
}

static constexpr bool GrIsPrimTypeTris(GrPrimitiveType type) {
    return GrPrimitiveType::kTriangles == type || GrPrimitiveType::kTriangleStrip == type;
}

enum class GrPrimitiveRestart : bool {
    kNo = false,
    kYes = true
};

struct GrDrawIndirectCommand {
    uint32_t fVertexCount;
    uint32_t fInstanceCount;
    uint32_t fBaseVertex;
    uint32_t fBaseInstance;
};

static_assert(sizeof(GrDrawIndirectCommand) == 16, "GrDrawIndirectCommand must be tightly packed");

struct GrDrawIndexedIndirectCommand {
    uint32_t fIndexCount;
    uint32_t fInstanceCount;
    uint32_t fBaseIndex;
    int32_t fBaseVertex;
    uint32_t fBaseInstance;
};

static_assert(sizeof(GrDrawIndexedIndirectCommand) == 20,
              "GrDrawIndexedIndirectCommand must be tightly packed");

/**
 * Should a created surface be texturable?
 */
enum class GrTexturable : bool {
    kNo = false,
    kYes = true
};

// A DDL recorder has its own proxy provider and proxy cache. This enum indicates if
// a given proxy provider is one of these special ones.
enum class GrDDLProvider : bool {
    kNo = false,
    kYes = true
};

/**
 *  Formats for masks, used by the font cache. Important that these are 0-based.
 */
enum GrMaskFormat {
    kA8_GrMaskFormat,    //!< 1-byte per pixel
    kA565_GrMaskFormat,  //!< 2-bytes per pixel, RGB represent 3-channel LCD coverage
    kARGB_GrMaskFormat,  //!< 4-bytes per pixel, color format

    kLast_GrMaskFormat = kARGB_GrMaskFormat
};
static const int kMaskFormatCount = kLast_GrMaskFormat + 1;

/**
 *  Return the number of bytes-per-pixel for the specified mask format.
 */
static inline int GrMaskFormatBytesPerPixel(GrMaskFormat format) {
    SkASSERT(format < kMaskFormatCount);
    // kA8   (0) -> 1
    // kA565 (1) -> 2
    // kARGB (2) -> 4
    static const int sBytesPerPixel[] = {1, 2, 4};
    static_assert(SK_ARRAY_COUNT(sBytesPerPixel) == kMaskFormatCount, "array_size_mismatch");
    static_assert(kA8_GrMaskFormat == 0, "enum_order_dependency");
    static_assert(kA565_GrMaskFormat == 1, "enum_order_dependency");
    static_assert(kARGB_GrMaskFormat == 2, "enum_order_dependency");

    return sBytesPerPixel[(int)format];
}

/** Ownership rules for external GPU resources imported into Skia. */
enum GrWrapOwnership {
    /** Skia will assume the client will keep the resource alive and Skia will not free it. */
    kBorrow_GrWrapOwnership,

    /** Skia will assume ownership of the resource and free it. */
    kAdopt_GrWrapOwnership,
};

enum class GrWrapCacheable : bool {
    /**
     * The wrapped resource will be removed from the cache as soon as it becomes purgeable. It may
     * still be assigned and found by a unique key, but the presence of the key will not be used to
     * keep the resource alive when it has no references.
     */
    kNo = false,
    /**
     * The wrapped resource is allowed to remain in the GrResourceCache when it has no references
     * but has a unique key. Such resources should only be given unique keys when it is known that
     * the key will eventually be removed from the resource or invalidated via the message bus.
     */
    kYes = true
};

enum class GrBudgetedType : uint8_t {
    /** The resource is budgeted and is subject to purging under budget pressure. */
    kBudgeted,
    /**
     * The resource is unbudgeted and is purged as soon as it has no refs regardless of whether
     * it has a unique or scratch key.
     */
    kUnbudgetedUncacheable,
    /**
     * The resource is unbudgeted and is allowed to remain in the cache with no refs if it
     * has a unique key. Scratch keys are ignored.
     */
    kUnbudgetedCacheable,
};

/**
 * Clips are composed from these objects.
 */
enum GrClipType {
    kRect_ClipType,
    kPath_ClipType
};

enum class GrScissorTest : bool {
    kDisabled = false,
    kEnabled = true
};

struct GrMipLevel {
    const void* fPixels = nullptr;
    size_t fRowBytes = 0;
};

/**
 * This enum is used to specify the load operation to be used when an GrOpsTask/GrOpsRenderPass
 * begins execution.
 */
enum class GrLoadOp {
    kLoad,
    kClear,
    kDiscard,
};

/**
 * This enum is used to specify the store operation to be used when an GrOpsTask/GrOpsRenderPass
 * ends execution.
 */
enum class GrStoreOp {
    kStore,
    kDiscard,
};

/**
 * Used to control antialiasing in draw calls.
 */
enum class GrAA : bool {
    kNo = false,
    kYes = true
};

enum class GrFillRule : bool {
    kNonzero,
    kEvenOdd
};

inline GrFillRule GrFillRuleForSkPath(const SkPath& path) {
    switch (path.getFillType()) {
        case SkPathFillType::kWinding:
        case SkPathFillType::kInverseWinding:
            return GrFillRule::kNonzero;
        case SkPathFillType::kEvenOdd:
        case SkPathFillType::kInverseEvenOdd:
            return GrFillRule::kEvenOdd;
    }
    SkUNREACHABLE;
}

/** This enum indicates the type of antialiasing to be performed. */
enum class GrAAType : unsigned {
    /** No antialiasing */
    kNone,
    /** Use fragment shader code or mixed samples to blend with a fractional pixel coverage. */
    kCoverage,
    /** Use normal MSAA. */
    kMSAA,

    kLast = kMSAA
};
static const int kGrAATypeCount = static_cast<int>(GrAAType::kLast) + 1;

static constexpr bool GrAATypeIsHW(GrAAType type) {
    switch (type) {
        case GrAAType::kNone:
            return false;
        case GrAAType::kCoverage:
            return false;
        case GrAAType::kMSAA:
            return true;
    }
    SkUNREACHABLE;
}

/**
 * Some pixel configs are inherently clamped to [0,1], some are allowed to go outside that range,
 * and some are FP but manually clamped in the XP.
 */
enum class GrClampType {
    kAuto,    // Normalized, fixed-point configs
    kManual,  // Clamped FP configs
    kNone,    // Normal (unclamped) FP configs
};

/**
 * A number of rectangle/quadrilateral drawing APIs can control anti-aliasing on a per edge basis.
 * These masks specify which edges are AA'ed. The intent for this is to support tiling with seamless
 * boundaries, where the inner edges are non-AA and the outer edges are AA. Regular draws (where AA
 * is specified by GrAA) is almost equivalent to kNone or kAll, with the exception of how MSAA is
 * handled.
 *
 * When tiling and there is MSAA, mixed edge rectangles are processed with MSAA, so in order for the
 * tiled edges to remain seamless, inner tiles with kNone must also be processed with MSAA. In
 * regular drawing, however, kNone should disable MSAA (if it's supported) to match the expected
 * appearance.
 *
 * Therefore, APIs that use per-edge AA flags also take a GrAA value so that they can differentiate
 * between the regular and tiling use case behaviors. Tiling operations should always pass
 * GrAA::kYes while regular options should pass GrAA based on the SkPaint's anti-alias state.
 *
 * These values are identical to SkCanvas::QuadAAFlags.
 */
enum class GrQuadAAFlags {
    kLeft   = 0b0001,
    kTop    = 0b0010,
    kRight  = 0b0100,
    kBottom = 0b1000,

    kNone = 0b0000,
    kAll  = 0b1111,
};

GR_MAKE_BITFIELD_CLASS_OPS(GrQuadAAFlags)

static inline GrQuadAAFlags SkToGrQuadAAFlags(unsigned flags) {
    return static_cast<GrQuadAAFlags>(flags);
}

/**
 * Types of shader-language-specific boxed variables we can create.
 */
enum GrSLType {
    kVoid_GrSLType,
    kBool_GrSLType,
    kByte_GrSLType,
    kByte2_GrSLType,
    kByte3_GrSLType,
    kByte4_GrSLType,
    kUByte_GrSLType,
    kUByte2_GrSLType,
    kUByte3_GrSLType,
    kUByte4_GrSLType,
    kShort_GrSLType,
    kShort2_GrSLType,
    kShort3_GrSLType,
    kShort4_GrSLType,
    kUShort_GrSLType,
    kUShort2_GrSLType,
    kUShort3_GrSLType,
    kUShort4_GrSLType,
    kFloat_GrSLType,
    kFloat2_GrSLType,
    kFloat3_GrSLType,
    kFloat4_GrSLType,
    kFloat2x2_GrSLType,
    kFloat3x3_GrSLType,
    kFloat4x4_GrSLType,
    kHalf_GrSLType,
    kHalf2_GrSLType,
    kHalf3_GrSLType,
    kHalf4_GrSLType,
    kHalf2x2_GrSLType,
    kHalf3x3_GrSLType,
    kHalf4x4_GrSLType,
    kInt_GrSLType,
    kInt2_GrSLType,
    kInt3_GrSLType,
    kInt4_GrSLType,
    kUint_GrSLType,
    kUint2_GrSLType,
    kTexture2DSampler_GrSLType,
    kTextureExternalSampler_GrSLType,
    kTexture2DRectSampler_GrSLType,
    kTexture2D_GrSLType,
    kSampler_GrSLType,

    kLast_GrSLType = kSampler_GrSLType
};
static const int kGrSLTypeCount = kLast_GrSLType + 1;

/**
 * The type of texture. Backends other than GL currently only use the 2D value but the type must
 * still be known at the API-neutral layer as it used to determine whether MIP maps, renderability,
 * and sampling parameters are legal for proxies that will be instantiated with wrapped textures.
 */
enum class GrTextureType {
    kNone,
    k2D,
    /* Rectangle uses unnormalized texture coordinates. */
    kRectangle,
    kExternal
};

enum GrShaderType {
    kVertex_GrShaderType,
    kGeometry_GrShaderType,
    kFragment_GrShaderType,

    kLastkFragment_GrShaderType = kFragment_GrShaderType
};
static const int kGrShaderTypeCount = kLastkFragment_GrShaderType + 1;

enum GrShaderFlags {
    kNone_GrShaderFlags = 0,
    kVertex_GrShaderFlag = 1,
    kTessControl_GrShaderFlag = 1 << 2,
    kTessEvaluation_GrShaderFlag = 1 << 2,
    kGeometry_GrShaderFlag = 1 << 3,
    kFragment_GrShaderFlag = 1 << 4
};
GR_MAKE_BITFIELD_OPS(GrShaderFlags)

/** Is the shading language type float (including vectors/matrices)? */
static constexpr bool GrSLTypeIsFloatType(GrSLType type) {
    switch (type) {
        case kFloat_GrSLType:
        case kFloat2_GrSLType:
        case kFloat3_GrSLType:
        case kFloat4_GrSLType:
        case kFloat2x2_GrSLType:
        case kFloat3x3_GrSLType:
        case kFloat4x4_GrSLType:
        case kHalf_GrSLType:
        case kHalf2_GrSLType:
        case kHalf3_GrSLType:
        case kHalf4_GrSLType:
        case kHalf2x2_GrSLType:
        case kHalf3x3_GrSLType:
        case kHalf4x4_GrSLType:
            return true;

        case kVoid_GrSLType:
        case kTexture2DSampler_GrSLType:
        case kTextureExternalSampler_GrSLType:
        case kTexture2DRectSampler_GrSLType:
        case kBool_GrSLType:
        case kByte_GrSLType:
        case kByte2_GrSLType:
        case kByte3_GrSLType:
        case kByte4_GrSLType:
        case kUByte_GrSLType:
        case kUByte2_GrSLType:
        case kUByte3_GrSLType:
        case kUByte4_GrSLType:
        case kShort_GrSLType:
        case kShort2_GrSLType:
        case kShort3_GrSLType:
        case kShort4_GrSLType:
        case kUShort_GrSLType:
        case kUShort2_GrSLType:
        case kUShort3_GrSLType:
        case kUShort4_GrSLType:
        case kInt_GrSLType:
        case kInt2_GrSLType:
        case kInt3_GrSLType:
        case kInt4_GrSLType:
        case kUint_GrSLType:
        case kUint2_GrSLType:
        case kTexture2D_GrSLType:
        case kSampler_GrSLType:
            return false;
    }
    SkUNREACHABLE;
}

/** If the type represents a single value or vector return the vector length, else -1. */
static constexpr int GrSLTypeVecLength(GrSLType type) {
    switch (type) {
        case kFloat_GrSLType:
        case kHalf_GrSLType:
        case kBool_GrSLType:
        case kByte_GrSLType:
        case kUByte_GrSLType:
        case kShort_GrSLType:
        case kUShort_GrSLType:
        case kInt_GrSLType:
        case kUint_GrSLType:
            return 1;

        case kFloat2_GrSLType:
        case kHalf2_GrSLType:
        case kByte2_GrSLType:
        case kUByte2_GrSLType:
        case kShort2_GrSLType:
        case kUShort2_GrSLType:
        case kInt2_GrSLType:
        case kUint2_GrSLType:
            return 2;

        case kFloat3_GrSLType:
        case kHalf3_GrSLType:
        case kByte3_GrSLType:
        case kUByte3_GrSLType:
        case kShort3_GrSLType:
        case kUShort3_GrSLType:
        case kInt3_GrSLType:
            return 3;

        case kFloat4_GrSLType:
        case kHalf4_GrSLType:
        case kByte4_GrSLType:
        case kUByte4_GrSLType:
        case kShort4_GrSLType:
        case kUShort4_GrSLType:
        case kInt4_GrSLType:
            return 4;

        case kFloat2x2_GrSLType:
        case kFloat3x3_GrSLType:
        case kFloat4x4_GrSLType:
        case kHalf2x2_GrSLType:
        case kHalf3x3_GrSLType:
        case kHalf4x4_GrSLType:
        case kVoid_GrSLType:
        case kTexture2DSampler_GrSLType:
        case kTextureExternalSampler_GrSLType:
        case kTexture2DRectSampler_GrSLType:
        case kTexture2D_GrSLType:
        case kSampler_GrSLType:
            return -1;
    }
    SkUNREACHABLE;
}

static inline GrSLType GrSLCombinedSamplerTypeForTextureType(GrTextureType type) {
    switch (type) {
        case GrTextureType::k2D:
            return kTexture2DSampler_GrSLType;
        case GrTextureType::kRectangle:
            return kTexture2DRectSampler_GrSLType;
        case GrTextureType::kExternal:
            return kTextureExternalSampler_GrSLType;
        default:
            SK_ABORT("Unexpected texture type");
    }
}

/** Rectangle and external textures only support the clamp wrap mode and do not support
 *  MIP maps.
 */
static inline bool GrTextureTypeHasRestrictedSampling(GrTextureType type) {
    switch (type) {
        case GrTextureType::k2D:
            return false;
        case GrTextureType::kRectangle:
            return true;
        case GrTextureType::kExternal:
            return true;
        default:
            SK_ABORT("Unexpected texture type");
    }
}

static constexpr bool GrSLTypeIsCombinedSamplerType(GrSLType type) {
    switch (type) {
        case kTexture2DSampler_GrSLType:
        case kTextureExternalSampler_GrSLType:
        case kTexture2DRectSampler_GrSLType:
            return true;

        case kVoid_GrSLType:
        case kFloat_GrSLType:
        case kFloat2_GrSLType:
        case kFloat3_GrSLType:
        case kFloat4_GrSLType:
        case kFloat2x2_GrSLType:
        case kFloat3x3_GrSLType:
        case kFloat4x4_GrSLType:
        case kHalf_GrSLType:
        case kHalf2_GrSLType:
        case kHalf3_GrSLType:
        case kHalf4_GrSLType:
        case kHalf2x2_GrSLType:
        case kHalf3x3_GrSLType:
        case kHalf4x4_GrSLType:
        case kInt_GrSLType:
        case kInt2_GrSLType:
        case kInt3_GrSLType:
        case kInt4_GrSLType:
        case kUint_GrSLType:
        case kUint2_GrSLType:
        case kBool_GrSLType:
        case kByte_GrSLType:
        case kByte2_GrSLType:
        case kByte3_GrSLType:
        case kByte4_GrSLType:
        case kUByte_GrSLType:
        case kUByte2_GrSLType:
        case kUByte3_GrSLType:
        case kUByte4_GrSLType:
        case kShort_GrSLType:
        case kShort2_GrSLType:
        case kShort3_GrSLType:
        case kShort4_GrSLType:
        case kUShort_GrSLType:
        case kUShort2_GrSLType:
        case kUShort3_GrSLType:
        case kUShort4_GrSLType:
        case kTexture2D_GrSLType:
        case kSampler_GrSLType:
            return false;
    }
    SkUNREACHABLE;
}

//////////////////////////////////////////////////////////////////////////////

/**
 * Types used to describe format of vertices in arrays.
 */
enum GrVertexAttribType {
    kFloat_GrVertexAttribType = 0,
    kFloat2_GrVertexAttribType,
    kFloat3_GrVertexAttribType,
    kFloat4_GrVertexAttribType,
    kHalf_GrVertexAttribType,
    kHalf2_GrVertexAttribType,
    kHalf4_GrVertexAttribType,

    kInt2_GrVertexAttribType,   // vector of 2 32-bit ints
    kInt3_GrVertexAttribType,   // vector of 3 32-bit ints
    kInt4_GrVertexAttribType,   // vector of 4 32-bit ints


    kByte_GrVertexAttribType,  // signed byte
    kByte2_GrVertexAttribType, // vector of 2 8-bit signed bytes
    kByte4_GrVertexAttribType, // vector of 4 8-bit signed bytes
    kUByte_GrVertexAttribType,  // unsigned byte
    kUByte2_GrVertexAttribType, // vector of 2 8-bit unsigned bytes
    kUByte4_GrVertexAttribType, // vector of 4 8-bit unsigned bytes

    kUByte_norm_GrVertexAttribType,  // unsigned byte, e.g. coverage, 0 -> 0.0f, 255 -> 1.0f.
    kUByte4_norm_GrVertexAttribType, // vector of 4 unsigned bytes, e.g. colors, 0 -> 0.0f,
                                     // 255 -> 1.0f.

    kShort2_GrVertexAttribType,       // vector of 2 16-bit shorts.
    kShort4_GrVertexAttribType,       // vector of 4 16-bit shorts.

    kUShort2_GrVertexAttribType,      // vector of 2 unsigned shorts. 0 -> 0, 65535 -> 65535.
    kUShort2_norm_GrVertexAttribType, // vector of 2 unsigned shorts. 0 -> 0.0f, 65535 -> 1.0f.

    kInt_GrVertexAttribType,
    kUint_GrVertexAttribType,

    kUShort_norm_GrVertexAttribType,

    kUShort4_norm_GrVertexAttribType, // vector of 4 unsigned shorts. 0 -> 0.0f, 65535 -> 1.0f.

    kLast_GrVertexAttribType = kUShort4_norm_GrVertexAttribType
};
static const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;

//////////////////////////////////////////////////////////////////////////////

static const int kGrClipEdgeTypeCnt = (int) GrClipEdgeType::kLast + 1;

static constexpr bool GrProcessorEdgeTypeIsFill(const GrClipEdgeType edgeType) {
    return (GrClipEdgeType::kFillAA == edgeType || GrClipEdgeType::kFillBW == edgeType);
}

static constexpr bool GrProcessorEdgeTypeIsInverseFill(const GrClipEdgeType edgeType) {
    return (GrClipEdgeType::kInverseFillAA == edgeType ||
            GrClipEdgeType::kInverseFillBW == edgeType);
}

static constexpr bool GrProcessorEdgeTypeIsAA(const GrClipEdgeType edgeType) {
    return (GrClipEdgeType::kFillBW != edgeType &&
            GrClipEdgeType::kInverseFillBW != edgeType);
}

static inline GrClipEdgeType GrInvertProcessorEdgeType(const GrClipEdgeType edgeType) {
    switch (edgeType) {
        case GrClipEdgeType::kFillBW:
            return GrClipEdgeType::kInverseFillBW;
        case GrClipEdgeType::kFillAA:
            return GrClipEdgeType::kInverseFillAA;
        case GrClipEdgeType::kInverseFillBW:
            return GrClipEdgeType::kFillBW;
        case GrClipEdgeType::kInverseFillAA:
            return GrClipEdgeType::kFillAA;
        case GrClipEdgeType::kHairlineAA:
            SK_ABORT("Hairline fill isn't invertible.");
    }
    return GrClipEdgeType::kFillAA;  // suppress warning.
}

/**
 * Indicates the type of pending IO operations that can be recorded for gpu resources.
 */
enum GrIOType {
    kRead_GrIOType,
    kWrite_GrIOType,
    kRW_GrIOType
};

/**
 * Indicates the type of data that a GPU buffer will be used for.
 */
enum class GrGpuBufferType {
    kVertex,
    kIndex,
    kDrawIndirect,
    kXferCpuToGpu,
    kXferGpuToCpu,
};
static const int kGrGpuBufferTypeCount = static_cast<int>(GrGpuBufferType::kXferGpuToCpu) + 1;

/**
 * Provides a performance hint regarding the frequency at which a data store will be accessed.
 */
enum GrAccessPattern {
    /** Data store will be respecified repeatedly and used many times. */
    kDynamic_GrAccessPattern,
    /** Data store will be specified once and used many times. (Thus disqualified from caching.) */
    kStatic_GrAccessPattern,
    /** Data store will be specified once and used at most a few times. (Also can't be cached.) */
    kStream_GrAccessPattern,

    kLast_GrAccessPattern = kStream_GrAccessPattern
};

// Flags shared between the GrSurface & GrSurfaceProxy class hierarchies
enum class GrInternalSurfaceFlags {
    kNone                           = 0,

    // Texture-level

    // Means the pixels in the texture are read-only. Cannot also be a GrRenderTarget[Proxy].
    kReadOnly                       = 1 << 0,

    // RT-level

    // This flag is for use with GL only. It tells us that the internal render target wraps FBO 0.
    kGLRTFBOIDIs0                   = 1 << 1,

    // This means the render target is multisampled, and internally holds a non-msaa texture for
    // resolving into. The render target resolves itself by blitting into this internal texture.
    // (asTexture() might or might not return the internal texture, but if it does, we always
    // resolve the render target before accessing this texture's data.)
    kRequiresManualMSAAResolve      = 1 << 2,

    // This means the pixels in the render target are write-only. This is used for Dawn and Metal
    // swap chain targets which can be rendered to, but not read or copied.
    kFramebufferOnly                = 1 << 3,
};

GR_MAKE_BITFIELD_CLASS_OPS(GrInternalSurfaceFlags)

// 'GR_MAKE_BITFIELD_CLASS_OPS' defines the & operator on GrInternalSurfaceFlags to return bool.
// We want to find the bitwise & with these masks, so we declare them as ints.
constexpr static int kGrInternalTextureFlagsMask = static_cast<int>(
        GrInternalSurfaceFlags::kReadOnly);

constexpr static int kGrInternalRenderTargetFlagsMask = static_cast<int>(
        GrInternalSurfaceFlags::kGLRTFBOIDIs0 | GrInternalSurfaceFlags::kRequiresManualMSAAResolve);

constexpr static int kGrInternalTextureRenderTargetFlagsMask =
        kGrInternalTextureFlagsMask | kGrInternalRenderTargetFlagsMask;

#ifdef SK_DEBUG
// Takes a pointer to a GrCaps, and will suppress prints if required
#define GrCapsDebugf(caps, ...)  if (!(caps)->suppressPrints()) SkDebugf(__VA_ARGS__)
#else
#define GrCapsDebugf(caps, ...) do {} while (0)
#endif

/**
 * Specifies if the holder owns the backend, OpenGL or Vulkan, object.
 */
enum class GrBackendObjectOwnership : bool {
    /** Holder does not destroy the backend object. */
    kBorrowed = false,
    /** Holder destroys the backend object. */
    kOwned = true
};

/*
 * Object for CPU-GPU synchronization
 */
typedef uint64_t GrFence;

/**
 * Used to include or exclude specific GPU path renderers for testing purposes.
 */
enum class GpuPathRenderers {
    kNone              =   0,  // Always use software masks and/or GrDefaultPathRenderer.
    kDashLine          =   1 << 0,
    kTessellation      =   1 << 1,
    kStencilAndCover   =   1 << 2,
    kCoverageCounting  =   1 << 3,
    kAAHairline        =   1 << 4,
    kAAConvex          =   1 << 5,
    kAALinearizing     =   1 << 6,
    kSmall             =   1 << 7,
    kTriangulating     =   1 << 8,
    kDefault           = ((1 << 9) - 1) & ~kTessellation  // All but kTessellation.
};

/**
 * Used to describe the current state of Mips on a GrTexture
 */
enum class  GrMipMapsStatus {
    kNotAllocated, // Mips have not been allocated
    kDirty,        // Mips are allocated but the full mip tree does not have valid data
    kValid,        // All levels fully allocated and have valid data in them
};

GR_MAKE_BITFIELD_CLASS_OPS(GpuPathRenderers)

/**
 * Like SkColorType this describes a layout of pixel data in CPU memory. It specifies the channels,
 * their type, and width. This exists so that the GPU backend can have private types that have no
 * analog in the public facing SkColorType enum and omit types not implemented in the GPU backend.
 * It does not refer to a texture format and the mapping to texture formats may be many-to-many.
 * It does not specify the sRGB encoding of the stored values. The components are listed in order of
 * where they appear in memory. In other words the first component listed is in the low bits and
 * the last component in the high bits.
 */
enum class GrColorType {
    kUnknown,
    kAlpha_8,
    kBGR_565,
    kABGR_4444,  // This name differs from SkColorType. kARGB_4444_SkColorType is misnamed.
    kRGBA_8888,
    kRGBA_8888_SRGB,
    kRGB_888x,
    kRG_88,
    kBGRA_8888,
    kRGBA_1010102,
    kBGRA_1010102,
    kGray_8,
    kAlpha_F16,
    kRGBA_F16,
    kRGBA_F16_Clamped,
    kRGBA_F32,

    kAlpha_16,
    kRG_1616,
    kRG_F16,
    kRGBA_16161616,

    // Unusual types that come up after reading back in cases where we are reassigning the meaning
    // of a texture format's channels to use for a particular color format but have to read back the
    // data to a full RGBA quadruple. (e.g. using a R8 texture format as A8 color type but the API
    // only supports reading to RGBA8.) None of these have SkColorType equivalents.
    kAlpha_8xxx,
    kAlpha_F32xxx,
    kGray_8xxx,

    // Types used to initialize backend textures.
    kRGB_888,
    kR_8,
    kR_16,
    kR_F16,
    kGray_F16,

    kLast = kGray_F16
};

static const int kGrColorTypeCnt = static_cast<int>(GrColorType::kLast) + 1;

static constexpr SkColorType GrColorTypeToSkColorType(GrColorType ct) {
    switch (ct) {
        case GrColorType::kUnknown:          return kUnknown_SkColorType;
        case GrColorType::kAlpha_8:          return kAlpha_8_SkColorType;
        case GrColorType::kBGR_565:          return kRGB_565_SkColorType;
        case GrColorType::kABGR_4444:        return kARGB_4444_SkColorType;
        case GrColorType::kRGBA_8888:        return kRGBA_8888_SkColorType;
        // Once we add kRGBA_8888_SRGB_SkColorType we should return that here.
        case GrColorType::kRGBA_8888_SRGB:   return kRGBA_8888_SkColorType;
        case GrColorType::kRGB_888x:         return kRGB_888x_SkColorType;
        case GrColorType::kRG_88:            return kR8G8_unorm_SkColorType;
        case GrColorType::kBGRA_8888:        return kBGRA_8888_SkColorType;
        case GrColorType::kRGBA_1010102:     return kRGBA_1010102_SkColorType;
        case GrColorType::kBGRA_1010102:     return kBGRA_1010102_SkColorType;
        case GrColorType::kGray_8:           return kGray_8_SkColorType;
        case GrColorType::kAlpha_F16:        return kA16_float_SkColorType;
        case GrColorType::kRGBA_F16:         return kRGBA_F16_SkColorType;
        case GrColorType::kRGBA_F16_Clamped: return kRGBA_F16Norm_SkColorType;
        case GrColorType::kRGBA_F32:         return kRGBA_F32_SkColorType;
        case GrColorType::kAlpha_8xxx:       return kUnknown_SkColorType;
        case GrColorType::kAlpha_F32xxx:     return kUnknown_SkColorType;
        case GrColorType::kGray_8xxx:        return kUnknown_SkColorType;
        case GrColorType::kAlpha_16:         return kA16_unorm_SkColorType;
        case GrColorType::kRG_1616:          return kR16G16_unorm_SkColorType;
        case GrColorType::kRGBA_16161616:    return kR16G16B16A16_unorm_SkColorType;
        case GrColorType::kRG_F16:           return kR16G16_float_SkColorType;
        case GrColorType::kRGB_888:          return kUnknown_SkColorType;
        case GrColorType::kR_8:              return kUnknown_SkColorType;
        case GrColorType::kR_16:             return kUnknown_SkColorType;
        case GrColorType::kR_F16:            return kUnknown_SkColorType;
        case GrColorType::kGray_F16:         return kUnknown_SkColorType;
    }
    SkUNREACHABLE;
}

static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct) {
    switch (ct) {
        case kUnknown_SkColorType:            return GrColorType::kUnknown;
        case kAlpha_8_SkColorType:            return GrColorType::kAlpha_8;
        case kRGB_565_SkColorType:            return GrColorType::kBGR_565;
        case kARGB_4444_SkColorType:          return GrColorType::kABGR_4444;
        case kRGBA_8888_SkColorType:          return GrColorType::kRGBA_8888;
        case kRGB_888x_SkColorType:           return GrColorType::kRGB_888x;
        case kBGRA_8888_SkColorType:          return GrColorType::kBGRA_8888;
        case kGray_8_SkColorType:             return GrColorType::kGray_8;
        case kRGBA_F16Norm_SkColorType:       return GrColorType::kRGBA_F16_Clamped;
        case kRGBA_F16_SkColorType:           return GrColorType::kRGBA_F16;
        case kRGBA_1010102_SkColorType:       return GrColorType::kRGBA_1010102;
        case kRGB_101010x_SkColorType:        return GrColorType::kUnknown;
        case kBGRA_1010102_SkColorType:       return GrColorType::kBGRA_1010102;
        case kBGR_101010x_SkColorType:        return GrColorType::kUnknown;
        case kRGBA_F32_SkColorType:           return GrColorType::kRGBA_F32;
        case kR8G8_unorm_SkColorType:         return GrColorType::kRG_88;
        case kA16_unorm_SkColorType:          return GrColorType::kAlpha_16;
        case kR16G16_unorm_SkColorType:       return GrColorType::kRG_1616;
        case kA16_float_SkColorType:          return GrColorType::kAlpha_F16;
        case kR16G16_float_SkColorType:       return GrColorType::kRG_F16;
        case kR16G16B16A16_unorm_SkColorType: return GrColorType::kRGBA_16161616;
    }
    SkUNREACHABLE;
}

// This is a temporary means of mapping an SkColorType and format to a
// GrColorType::kRGBA_8888_SRGB. Once we have an SRGB SkColorType this can go away.
GrColorType SkColorTypeAndFormatToGrColorType(const GrCaps* caps,
                                              SkColorType skCT,
                                              const GrBackendFormat& format);

static constexpr uint32_t GrColorTypeChannelFlags(GrColorType ct) {
    switch (ct) {
        case GrColorType::kUnknown:          return 0;
        case GrColorType::kAlpha_8:          return kAlpha_SkColorChannelFlag;
        case GrColorType::kBGR_565:          return kRGB_SkColorChannelFlags;
        case GrColorType::kABGR_4444:        return kRGBA_SkColorChannelFlags;
        case GrColorType::kRGBA_8888:        return kRGBA_SkColorChannelFlags;
        case GrColorType::kRGBA_8888_SRGB:   return kRGBA_SkColorChannelFlags;
        case GrColorType::kRGB_888x:         return kRGB_SkColorChannelFlags;
        case GrColorType::kRG_88:            return kRG_SkColorChannelFlags;
        case GrColorType::kBGRA_8888:        return kRGBA_SkColorChannelFlags;
        case GrColorType::kRGBA_1010102:     return kRGBA_SkColorChannelFlags;
        case GrColorType::kBGRA_1010102:     return kRGBA_SkColorChannelFlags;
        case GrColorType::kGray_8:           return kGray_SkColorChannelFlag;
        case GrColorType::kAlpha_F16:        return kAlpha_SkColorChannelFlag;
        case GrColorType::kRGBA_F16:         return kRGBA_SkColorChannelFlags;
        case GrColorType::kRGBA_F16_Clamped: return kRGBA_SkColorChannelFlags;
        case GrColorType::kRGBA_F32:         return kRGBA_SkColorChannelFlags;
        case GrColorType::kAlpha_8xxx:       return kAlpha_SkColorChannelFlag;
        case GrColorType::kAlpha_F32xxx:     return kAlpha_SkColorChannelFlag;
        case GrColorType::kGray_8xxx:        return kGray_SkColorChannelFlag;
        case GrColorType::kAlpha_16:         return kAlpha_SkColorChannelFlag;
        case GrColorType::kRG_1616:          return kRG_SkColorChannelFlags;
        case GrColorType::kRGBA_16161616:    return kRGBA_SkColorChannelFlags;
        case GrColorType::kRG_F16:           return kRG_SkColorChannelFlags;
        case GrColorType::kRGB_888:          return kRGB_SkColorChannelFlags;
        case GrColorType::kR_8:              return kRed_SkColorChannelFlag;
        case GrColorType::kR_16:             return kRed_SkColorChannelFlag;
        case GrColorType::kR_F16:            return kRed_SkColorChannelFlag;
        case GrColorType::kGray_F16:         return kGray_SkColorChannelFlag;
    }
    SkUNREACHABLE;
}

/**
 * Describes the encoding of channel data in a GrColorType.
 */
enum class GrColorTypeEncoding {
    kUnorm,
    kSRGBUnorm,
    // kSnorm,
    kFloat,
    // kSint
    // kUint
};

/**
 * Describes a GrColorType by how many bits are used for each color component and how they are
 * encoded. Currently all the non-zero channels share a single GrColorTypeEncoding. This could be
 * expanded to store separate encodings and to indicate which bits belong to which components.
 */
struct GrColorTypeDesc {
public:
    static constexpr GrColorTypeDesc MakeRGBA(int rgba, GrColorTypeEncoding e) {
        return {rgba, rgba, rgba, rgba, 0, e};
    }

    static constexpr GrColorTypeDesc MakeRGBA(int rgb, int a, GrColorTypeEncoding e) {
        return {rgb, rgb, rgb, a, 0, e};
    }

    static constexpr GrColorTypeDesc MakeRGB(int rgb, GrColorTypeEncoding e) {
        return {rgb, rgb, rgb, 0, 0, e};
    }

    static constexpr GrColorTypeDesc MakeRGB(int r, int g, int b, GrColorTypeEncoding e) {
        return {r, g, b, 0, 0, e};
    }

    static constexpr GrColorTypeDesc MakeAlpha(int a, GrColorTypeEncoding e) {
        return {0, 0, 0, a, 0, e};
    }

    static constexpr GrColorTypeDesc MakeR(int r, GrColorTypeEncoding e) {
        return {r, 0, 0, 0, 0, e};
    }

    static constexpr GrColorTypeDesc MakeRG(int rg, GrColorTypeEncoding e) {
        return {rg, rg, 0, 0, 0, e};
    }

    static constexpr GrColorTypeDesc MakeGray(int grayBits, GrColorTypeEncoding e) {
        return {0, 0, 0, 0, grayBits, e};
    }

    static constexpr GrColorTypeDesc MakeInvalid() { return {}; }

    constexpr int r() const { return fRBits; }
    constexpr int g() const { return fGBits; }
    constexpr int b() const { return fBBits; }
    constexpr int a() const { return fABits; }
    constexpr int operator[](int c) const {
        switch (c) {
            case 0: return this->r();
            case 1: return this->g();
            case 2: return this->b();
            case 3: return this->a();
        }
        SkUNREACHABLE;
    }

    constexpr int gray() const { return fGrayBits; }

    constexpr GrColorTypeEncoding encoding() const { return fEncoding; }

private:
    int fRBits = 0;
    int fGBits = 0;
    int fBBits = 0;
    int fABits = 0;
    int fGrayBits = 0;
    GrColorTypeEncoding fEncoding = GrColorTypeEncoding::kUnorm;

    constexpr GrColorTypeDesc() = default;

    constexpr GrColorTypeDesc(int r, int g, int b, int a, int gray, GrColorTypeEncoding encoding)
            : fRBits(r), fGBits(g), fBBits(b), fABits(a), fGrayBits(gray), fEncoding(encoding) {
        SkASSERT(r >= 0 && g >= 0 && b >= 0 && a >= 0 && gray >= 0);
        SkASSERT(!gray || (!r && !g && !b));
        SkASSERT(r || g || b || a || gray);
    }
};

static constexpr GrColorTypeDesc GrGetColorTypeDesc(GrColorType ct) {
    switch (ct) {
        case GrColorType::kUnknown:
            return GrColorTypeDesc::MakeInvalid();
        case GrColorType::kAlpha_8:
            return GrColorTypeDesc::MakeAlpha(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kBGR_565:
            return GrColorTypeDesc::MakeRGB(5, 6, 5, GrColorTypeEncoding::kUnorm);
        case GrColorType::kABGR_4444:
            return GrColorTypeDesc::MakeRGBA(4, GrColorTypeEncoding::kUnorm);
        case GrColorType::kRGBA_8888:
            return GrColorTypeDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kRGBA_8888_SRGB:
            return GrColorTypeDesc::MakeRGBA(8, GrColorTypeEncoding::kSRGBUnorm);
        case GrColorType::kRGB_888x:
            return GrColorTypeDesc::MakeRGB(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kRG_88:
            return GrColorTypeDesc::MakeRG(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kBGRA_8888:
            return GrColorTypeDesc::MakeRGBA(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kRGBA_1010102:
            return GrColorTypeDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
        case GrColorType::kBGRA_1010102:
            return GrColorTypeDesc::MakeRGBA(10, 2, GrColorTypeEncoding::kUnorm);
        case GrColorType::kGray_8:
            return GrColorTypeDesc::MakeGray(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kAlpha_F16:
            return GrColorTypeDesc::MakeAlpha(16, GrColorTypeEncoding::kFloat);
        case GrColorType::kRGBA_F16:
            return GrColorTypeDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
        case GrColorType::kRGBA_F16_Clamped:
            return GrColorTypeDesc::MakeRGBA(16, GrColorTypeEncoding::kFloat);
        case GrColorType::kRGBA_F32:
            return GrColorTypeDesc::MakeRGBA(32, GrColorTypeEncoding::kFloat);
        case GrColorType::kAlpha_8xxx:
            return GrColorTypeDesc::MakeAlpha(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kAlpha_F32xxx:
            return GrColorTypeDesc::MakeAlpha(32, GrColorTypeEncoding::kFloat);
        case GrColorType::kGray_8xxx:
            return GrColorTypeDesc::MakeGray(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kAlpha_16:
            return GrColorTypeDesc::MakeAlpha(16, GrColorTypeEncoding::kUnorm);
        case GrColorType::kRG_1616:
            return GrColorTypeDesc::MakeRG(16, GrColorTypeEncoding::kUnorm);
        case GrColorType::kRGBA_16161616:
            return GrColorTypeDesc::MakeRGBA(16, GrColorTypeEncoding::kUnorm);
        case GrColorType::kRG_F16:
            return GrColorTypeDesc::MakeRG(16, GrColorTypeEncoding::kFloat);
        case GrColorType::kRGB_888:
            return GrColorTypeDesc::MakeRGB(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kR_8:
            return GrColorTypeDesc::MakeR(8, GrColorTypeEncoding::kUnorm);
        case GrColorType::kR_16:
            return GrColorTypeDesc::MakeR(16, GrColorTypeEncoding::kUnorm);
        case GrColorType::kR_F16:
            return GrColorTypeDesc::MakeR(16, GrColorTypeEncoding::kFloat);
        case GrColorType::kGray_F16:
            return GrColorTypeDesc::MakeGray(16, GrColorTypeEncoding::kFloat);
    }
    SkUNREACHABLE;
}

static constexpr GrClampType GrColorTypeClampType(GrColorType colorType) {
    if (GrGetColorTypeDesc(colorType).encoding() == GrColorTypeEncoding::kUnorm ||
        GrGetColorTypeDesc(colorType).encoding() == GrColorTypeEncoding::kSRGBUnorm) {
        return GrClampType::kAuto;
    }
    return GrColorType::kRGBA_F16_Clamped == colorType ? GrClampType::kManual : GrClampType::kNone;
}

// Consider a color type "wider" than n if it has more than n bits for any its representable
// channels.
static constexpr bool GrColorTypeIsWiderThan(GrColorType colorType, int n) {
    SkASSERT(n > 0);
    auto desc = GrGetColorTypeDesc(colorType);
    return (desc.r() && desc.r() > n )||
           (desc.g() && desc.g() > n) ||
           (desc.b() && desc.b() > n) ||
           (desc.a() && desc.a() > n) ||
           (desc.gray() && desc.gray() > n);
}

static constexpr bool GrColorTypeIsAlphaOnly(GrColorType ct) {
    return GrColorTypeChannelFlags(ct) == kAlpha_SkColorChannelFlag;
}

static constexpr bool GrColorTypeHasAlpha(GrColorType ct) {
    return GrColorTypeChannelFlags(ct) & kAlpha_SkColorChannelFlag;
}

static constexpr size_t GrColorTypeBytesPerPixel(GrColorType ct) {
    switch (ct) {
        case GrColorType::kUnknown:          return 0;
        case GrColorType::kAlpha_8:          return 1;
        case GrColorType::kBGR_565:          return 2;
        case GrColorType::kABGR_4444:        return 2;
        case GrColorType::kRGBA_8888:        return 4;
        case GrColorType::kRGBA_8888_SRGB:   return 4;
        case GrColorType::kRGB_888x:         return 4;
        case GrColorType::kRG_88:            return 2;
        case GrColorType::kBGRA_8888:        return 4;
        case GrColorType::kRGBA_1010102:     return 4;
        case GrColorType::kBGRA_1010102:     return 4;
        case GrColorType::kGray_8:           return 1;
        case GrColorType::kAlpha_F16:        return 2;
        case GrColorType::kRGBA_F16:         return 8;
        case GrColorType::kRGBA_F16_Clamped: return 8;
        case GrColorType::kRGBA_F32:         return 16;
        case GrColorType::kAlpha_8xxx:       return 4;
        case GrColorType::kAlpha_F32xxx:     return 16;
        case GrColorType::kGray_8xxx:        return 4;
        case GrColorType::kAlpha_16:         return 2;
        case GrColorType::kRG_1616:          return 4;
        case GrColorType::kRGBA_16161616:    return 8;
        case GrColorType::kRG_F16:           return 4;
        case GrColorType::kRGB_888:          return 3;
        case GrColorType::kR_8:              return 1;
        case GrColorType::kR_16:             return 2;
        case GrColorType::kR_F16:            return 2;
        case GrColorType::kGray_F16:         return 2;
    }
    SkUNREACHABLE;
}

// In general we try to not mix CompressionType and ColorType, but currently SkImage still requires
// an SkColorType even for CompressedTypes so we need some conversion.
static constexpr SkColorType GrCompressionTypeToSkColorType(SkImage::CompressionType compression) {
    switch (compression) {
        case SkImage::CompressionType::kNone:            return kUnknown_SkColorType;
        case SkImage::CompressionType::kETC2_RGB8_UNORM: return kRGB_888x_SkColorType;
        case SkImage::CompressionType::kBC1_RGB8_UNORM:  return kRGB_888x_SkColorType;
        case SkImage::CompressionType::kBC1_RGBA8_UNORM: return kRGBA_8888_SkColorType;
    }

    SkUNREACHABLE;
}

static constexpr GrColorType GrMaskFormatToColorType(GrMaskFormat format) {
    switch (format) {
        case kA8_GrMaskFormat:
            return GrColorType::kAlpha_8;
        case kA565_GrMaskFormat:
            return GrColorType::kBGR_565;
        case kARGB_GrMaskFormat:
            return GrColorType::kRGBA_8888;
    }
    SkUNREACHABLE;
}

/**
 * Ref-counted object that calls a callback from its destructor.
 */
class GrRefCntedCallback : public SkRefCnt {
public:
    using Context = void*;
    using Callback = void (*)(Context);

    GrRefCntedCallback(Callback proc, Context ctx) : fReleaseProc(proc), fReleaseCtx(ctx) {
        SkASSERT(proc);
    }
    ~GrRefCntedCallback() override { fReleaseProc ? fReleaseProc(fReleaseCtx) : void(); }

    Context context() const { return fReleaseCtx; }

private:
    Callback fReleaseProc;
    Context fReleaseCtx;
};

#if GR_TEST_UTILS || defined(SK_ENABLE_DUMP_GPU)
static constexpr const char* GrBackendApiToStr(GrBackendApi api) {
    switch (api) {
        case GrBackendApi::kOpenGL:   return "OpenGL";
        case GrBackendApi::kVulkan:   return "Vulkan";
        case GrBackendApi::kMetal:    return "Metal";
        case GrBackendApi::kDirect3D: return "Direct3D";
        case GrBackendApi::kDawn:     return "Dawn";
        case GrBackendApi::kMock:     return "Mock";
    }
    SkUNREACHABLE;
}

static constexpr const char* GrColorTypeToStr(GrColorType ct) {
    switch (ct) {
        case GrColorType::kUnknown:          return "kUnknown";
        case GrColorType::kAlpha_8:          return "kAlpha_8";
        case GrColorType::kBGR_565:          return "kRGB_565";
        case GrColorType::kABGR_4444:        return "kABGR_4444";
        case GrColorType::kRGBA_8888:        return "kRGBA_8888";
        case GrColorType::kRGBA_8888_SRGB:   return "kRGBA_8888_SRGB";
        case GrColorType::kRGB_888x:         return "kRGB_888x";
        case GrColorType::kRG_88:            return "kRG_88";
        case GrColorType::kBGRA_8888:        return "kBGRA_8888";
        case GrColorType::kRGBA_1010102:     return "kRGBA_1010102";
        case GrColorType::kBGRA_1010102:     return "kBGRA_1010102";
        case GrColorType::kGray_8:           return "kGray_8";
        case GrColorType::kAlpha_F16:        return "kAlpha_F16";
        case GrColorType::kRGBA_F16:         return "kRGBA_F16";
        case GrColorType::kRGBA_F16_Clamped: return "kRGBA_F16_Clamped";
        case GrColorType::kRGBA_F32:         return "kRGBA_F32";
        case GrColorType::kAlpha_8xxx:       return "kAlpha_8xxx";
        case GrColorType::kAlpha_F32xxx:     return "kAlpha_F32xxx";
        case GrColorType::kGray_8xxx:        return "kGray_8xxx";
        case GrColorType::kAlpha_16:         return "kAlpha_16";
        case GrColorType::kRG_1616:          return "kRG_1616";
        case GrColorType::kRGBA_16161616:    return "kRGBA_16161616";
        case GrColorType::kRG_F16:           return "kRG_F16";
        case GrColorType::kRGB_888:          return "kRGB_888";
        case GrColorType::kR_8:              return "kR_8";
        case GrColorType::kR_16:             return "kR_16";
        case GrColorType::kR_F16:            return "kR_F16";
        case GrColorType::kGray_F16:         return "kGray_F16";
    }
    SkUNREACHABLE;
}

static constexpr const char* GrCompressionTypeToStr(SkImage::CompressionType compression) {
    switch (compression) {
        case SkImage::CompressionType::kNone:            return "kNone";
        case SkImage::CompressionType::kETC2_RGB8_UNORM: return "kETC2_RGB8_UNORM";
        case SkImage::CompressionType::kBC1_RGB8_UNORM:  return "kBC1_RGB8_UNORM";
        case SkImage::CompressionType::kBC1_RGBA8_UNORM: return "kBC1_RGBA8_UNORM";
    }
    SkUNREACHABLE;
}
#endif

#endif
