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

#include "src/gpu/ganesh/GrDataUtils.h"

#include "include/core/SkColorSpace.h"
#include "include/core/SkTextureCompressionType.h"
#include "include/private/base/SkTPin.h"
#include "modules/skcms/skcms.h"
#include "src/base/SkMathPriv.h"
#include "src/base/SkTLazy.h"
#include "src/base/SkUtils.h"
#include "src/core/SkColorSpaceXformSteps.h"
#include "src/core/SkCompressedDataUtils.h"
#include "src/core/SkConvertPixels.h"
#include "src/core/SkMipmap.h"
#include "src/core/SkRasterPipeline.h"
#include "src/core/SkTraceEvent.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColor.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrPixmap.h"

struct ETC1Block {
    uint32_t fHigh;
    uint32_t fLow;
};

constexpr uint32_t kDiffBit = 0x2; // set -> differential; not-set -> individual

static inline int extend_5To8bits(int b) {
    int c = b & 0x1f;
    return (c << 3) | (c >> 2);
}

static const int kNumETC1ModifierTables = 8;
static const int kNumETC1PixelIndices = 4;

// The index of each row in this table is the ETC1 table codeword
// The index of each column in this table is the ETC1 pixel index value
static const int kETC1ModifierTables[kNumETC1ModifierTables][kNumETC1PixelIndices] = {
    /* 0 */ { 2,    8,  -2,   -8 },
    /* 1 */ { 5,   17,  -5,  -17 },
    /* 2 */ { 9,   29,  -9,  -29 },
    /* 3 */ { 13,  42, -13,  -42 },
    /* 4 */ { 18,  60, -18,  -60 },
    /* 5 */ { 24,  80, -24,  -80 },
    /* 6 */ { 33, 106, -33, -106 },
    /* 7 */ { 47, 183, -47, -183 }
};

// Evaluate one of the entries in 'kModifierTables' to see how close it can get (r8,g8,b8) to
// the original color (rOrig, gOrib, bOrig).
static int test_table_entry(int rOrig, int gOrig, int bOrig,
                            int r8, int g8, int b8,
                            int table, int offset) {
    SkASSERT(0 <= table && table < 8);
    SkASSERT(0 <= offset && offset < 4);

    r8 = SkTPin<int>(r8 + kETC1ModifierTables[table][offset], 0, 255);
    g8 = SkTPin<int>(g8 + kETC1ModifierTables[table][offset], 0, 255);
    b8 = SkTPin<int>(b8 + kETC1ModifierTables[table][offset], 0, 255);

    return SkTAbs(rOrig - r8) + SkTAbs(gOrig - g8) + SkTAbs(bOrig - b8);
}

// Create an ETC1 compressed block that is filled with 'col'
static void create_etc1_block(SkColor col, ETC1Block* block) {
    uint32_t high = 0;
    uint32_t low = 0;

    int rOrig = SkColorGetR(col);
    int gOrig = SkColorGetG(col);
    int bOrig = SkColorGetB(col);

    int r5 = SkMulDiv255Round(31, rOrig);
    int g5 = SkMulDiv255Round(31, gOrig);
    int b5 = SkMulDiv255Round(31, bOrig);

    int r8 = extend_5To8bits(r5);
    int g8 = extend_5To8bits(g5);
    int b8 = extend_5To8bits(b5);

    // We always encode solid color textures in differential mode (i.e., with a 555 base color) but
    // with zero diffs (i.e., bits 26-24, 18-16 and 10-8 are left 0).
    high |= (r5 << 27) | (g5 << 19) | (b5 << 11) | kDiffBit;

    int bestTableIndex = 0, bestPixelIndex = 0;
    int bestSoFar = 1024;
    for (int tableIndex = 0; tableIndex < kNumETC1ModifierTables; ++tableIndex) {
        for (int pixelIndex = 0; pixelIndex < kNumETC1PixelIndices; ++pixelIndex) {
            int score = test_table_entry(rOrig, gOrig, bOrig, r8, g8, b8,
                                         tableIndex, pixelIndex);

            if (bestSoFar > score) {
                bestSoFar = score;
                bestTableIndex = tableIndex;
                bestPixelIndex = pixelIndex;
            }
        }
    }

    high |= (bestTableIndex << 5) | (bestTableIndex << 2);

    if (bestPixelIndex & 0x1) {
        low |= 0xFFFF;
    }
    if (bestPixelIndex & 0x2) {
        low |= 0xFFFF0000;
    }

    block->fHigh = SkBSwap32(high);
    block->fLow = SkBSwap32(low);
}

static int num_4x4_blocks(int size) {
    return ((size + 3) & ~3) >> 2;
}

static int num_ETC1_blocks(int w, int h) {
    w = num_4x4_blocks(w);
    h = num_4x4_blocks(h);

    return w * h;
}

struct BC1Block {
    uint16_t fColor0;
    uint16_t fColor1;
    uint32_t fIndices;
};

static uint16_t to565(SkColor col) {
    int r5 = SkMulDiv255Round(31, SkColorGetR(col));
    int g6 = SkMulDiv255Round(63, SkColorGetG(col));
    int b5 = SkMulDiv255Round(31, SkColorGetB(col));

    return (r5 << 11) | (g6 << 5) | b5;
}

// Create a BC1 compressed block that has two colors but is initialized to 'col0'
static void create_BC1_block(SkColor col0, SkColor col1, BC1Block* block) {
    block->fColor0 = to565(col0);
    block->fColor1 = to565(col1);
    SkASSERT(block->fColor0 <= block->fColor1); // we always assume transparent blocks

    if (col0 == SK_ColorTRANSPARENT) {
        // This sets all 16 pixels to just use color3 (under the assumption
        // that this is a kBC1_RGBA8_UNORM texture. Note that in this case
        // fColor0 will be opaque black.
        block->fIndices = 0xFFFFFFFF;
    } else {
        // This sets all 16 pixels to just use 'fColor0'
        block->fIndices = 0;
    }
}

size_t GrNumBlocks(SkTextureCompressionType type, SkISize baseDimensions) {
    switch (type) {
        case SkTextureCompressionType::kNone:
            return baseDimensions.width() * baseDimensions.height();
        case SkTextureCompressionType::kETC2_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGBA8_UNORM: {
            int numBlocksWidth = num_4x4_blocks(baseDimensions.width());
            int numBlocksHeight = num_4x4_blocks(baseDimensions.height());

            return numBlocksWidth * numBlocksHeight;
        }
    }
    SkUNREACHABLE;
}

size_t GrCompressedRowBytes(SkTextureCompressionType type, int width) {
    switch (type) {
        case SkTextureCompressionType::kNone:
            return 0;
        case SkTextureCompressionType::kETC2_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGBA8_UNORM: {
            int numBlocksWidth = num_4x4_blocks(width);

            static_assert(sizeof(ETC1Block) == sizeof(BC1Block));
            return numBlocksWidth * sizeof(ETC1Block);
        }
    }
    SkUNREACHABLE;
}

SkISize GrCompressedDimensions(SkTextureCompressionType type, SkISize baseDimensions) {
    switch (type) {
        case SkTextureCompressionType::kNone:
            return baseDimensions;
        case SkTextureCompressionType::kETC2_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGB8_UNORM:
        case SkTextureCompressionType::kBC1_RGBA8_UNORM: {
            int numBlocksWidth = num_4x4_blocks(baseDimensions.width());
            int numBlocksHeight = num_4x4_blocks(baseDimensions.height());

            // Each BC1_RGB8_UNORM and ETC1 block has 16 pixels
            return { 4 * numBlocksWidth, 4 * numBlocksHeight };
        }
    }
    SkUNREACHABLE;
}

// Fill in 'dest' with ETC1 blocks derived from 'colorf'
static void fillin_ETC1_with_color(SkISize dimensions, const SkColor4f& colorf, char* dest) {
    SkColor color = colorf.toSkColor();

    ETC1Block block;
    create_etc1_block(color, &block);

    int numBlocks = num_ETC1_blocks(dimensions.width(), dimensions.height());

    for (int i = 0; i < numBlocks; ++i) {
        memcpy(dest, &block, sizeof(ETC1Block));
        dest += sizeof(ETC1Block);
    }
}

// Fill in 'dest' with BC1 blocks derived from 'colorf'
static void fillin_BC1_with_color(SkISize dimensions, const SkColor4f& colorf, char* dest) {
    SkColor color = colorf.toSkColor();

    BC1Block block;
    create_BC1_block(color, color, &block);

    int numBlocks = num_ETC1_blocks(dimensions.width(), dimensions.height());

    for (int i = 0; i < numBlocks; ++i) {
        memcpy(dest, &block, sizeof(BC1Block));
        dest += sizeof(BC1Block);
    }
}

#if GR_TEST_UTILS

// Fill in 'dstPixels' with BC1 blocks derived from the 'pixmap'.
void GrTwoColorBC1Compress(const SkPixmap& pixmap, SkColor otherColor, char* dstPixels) {
    BC1Block* dstBlocks = reinterpret_cast<BC1Block*>(dstPixels);
    SkASSERT(pixmap.colorType() == SkColorType::kRGBA_8888_SkColorType);

    BC1Block block;

    // black -> fColor0, otherColor -> fColor1
    create_BC1_block(SK_ColorBLACK, otherColor, &block);

    int numXBlocks = num_4x4_blocks(pixmap.width());
    int numYBlocks = num_4x4_blocks(pixmap.height());

    for (int y = 0; y < numYBlocks; ++y) {
        for (int x = 0; x < numXBlocks; ++x) {
            int shift = 0;
            int offsetX = 4 * x, offsetY = 4 * y;
            block.fIndices = 0;  // init all the pixels to color0 (i.e., opaque black)
            for (int i = 0; i < 4; ++i) {
                for (int j = 0; j < 4; ++j, shift += 2) {
                    if (offsetX + j >= pixmap.width() || offsetY + i >= pixmap.height()) {
                        // This can happen for the topmost levels of a mipmap and for
                        // non-multiple of 4 textures
                        continue;
                    }

                    SkColor tmp = pixmap.getColor(offsetX + j, offsetY + i);
                    if (tmp == SK_ColorTRANSPARENT) {
                        // For RGBA BC1 images color3 is set to transparent black
                        block.fIndices |= 3 << shift;
                    } else if (tmp != SK_ColorBLACK) {
                        block.fIndices |= 1 << shift; // color1
                    }
                }
            }

            dstBlocks[y*numXBlocks + x] = block;
        }
    }
}

#endif

size_t GrComputeTightCombinedBufferSize(size_t bytesPerPixel, SkISize baseDimensions,
                                        SkTArray<size_t>* individualMipOffsets, int mipLevelCount) {
    SkASSERT(individualMipOffsets && !individualMipOffsets->size());
    SkASSERT(mipLevelCount >= 1);

    individualMipOffsets->push_back(0);

    size_t combinedBufferSize = baseDimensions.width() * bytesPerPixel * baseDimensions.height();
    SkISize levelDimensions = baseDimensions;

    // The Vulkan spec for copying a buffer to an image requires that the alignment must be at
    // least 4 bytes and a multiple of the bytes per pixel of the image config.
    SkASSERT(bytesPerPixel == 1 || bytesPerPixel == 2 || bytesPerPixel == 3 ||
             bytesPerPixel == 4 || bytesPerPixel == 8 || bytesPerPixel == 16);
    int desiredAlignment = (bytesPerPixel == 3) ? 12 : (bytesPerPixel > 4 ? bytesPerPixel : 4);

    for (int currentMipLevel = 1; currentMipLevel < mipLevelCount; ++currentMipLevel) {
        levelDimensions = {std::max(1, levelDimensions.width() /2),
                           std::max(1, levelDimensions.height()/2)};

        size_t trimmedSize = levelDimensions.area() * bytesPerPixel;
        const size_t alignmentDiff = combinedBufferSize % desiredAlignment;
        if (alignmentDiff != 0) {
            combinedBufferSize += desiredAlignment - alignmentDiff;
        }
        SkASSERT((0 == combinedBufferSize % 4) && (0 == combinedBufferSize % bytesPerPixel));

        individualMipOffsets->push_back(combinedBufferSize);
        combinedBufferSize += trimmedSize;
    }

    SkASSERT(individualMipOffsets->size() == mipLevelCount);
    return combinedBufferSize;
}

void GrFillInCompressedData(SkTextureCompressionType type, SkISize dimensions,
                            GrMipmapped mipmapped, char* dstPixels, const SkColor4f& colorf) {
    TRACE_EVENT0("skia.gpu", TRACE_FUNC);

    int numMipLevels = 1;
    if (mipmapped == GrMipmapped::kYes) {
        numMipLevels = SkMipmap::ComputeLevelCount(dimensions.width(), dimensions.height()) + 1;
    }

    size_t offset = 0;

    for (int i = 0; i < numMipLevels; ++i) {
        size_t levelSize = SkCompressedDataSize(type, dimensions, nullptr, false);

        if (SkTextureCompressionType::kETC2_RGB8_UNORM == type) {
            fillin_ETC1_with_color(dimensions, colorf, &dstPixels[offset]);
        } else {
            SkASSERT(type == SkTextureCompressionType::kBC1_RGB8_UNORM ||
                     type == SkTextureCompressionType::kBC1_RGBA8_UNORM);
            fillin_BC1_with_color(dimensions, colorf, &dstPixels[offset]);
        }

        offset += levelSize;
        dimensions = {std::max(1, dimensions.width()/2), std::max(1, dimensions.height()/2)};
    }
}

static skgpu::Swizzle get_load_and_src_swizzle(GrColorType ct, SkRasterPipelineOp* load,
                                               bool* isNormalized, bool* isSRGB) {
    skgpu::Swizzle swizzle("rgba");
    *isNormalized = true;
    *isSRGB = false;
    switch (ct) {
        case GrColorType::kAlpha_8:          *load = SkRasterPipelineOp::load_a8;       break;
        case GrColorType::kAlpha_16:         *load = SkRasterPipelineOp::load_a16;      break;
        case GrColorType::kBGR_565:          *load = SkRasterPipelineOp::load_565;      break;
        case GrColorType::kABGR_4444:        *load = SkRasterPipelineOp::load_4444;     break;
        case GrColorType::kARGB_4444:        swizzle = skgpu::Swizzle("bgra");
                                             *load = SkRasterPipelineOp::load_4444;     break;
        case GrColorType::kBGRA_4444:        swizzle = skgpu::Swizzle("gbar");
                                             *load = SkRasterPipelineOp::load_4444;     break;
        case GrColorType::kRGBA_8888:        *load = SkRasterPipelineOp::load_8888;     break;
        case GrColorType::kRG_88:            *load = SkRasterPipelineOp::load_rg88;     break;
        case GrColorType::kRGBA_1010102:     *load = SkRasterPipelineOp::load_1010102;  break;
        case GrColorType::kBGRA_1010102:     *load = SkRasterPipelineOp::load_1010102;
                                             swizzle = skgpu::Swizzle("bgra");
                                             break;
        case GrColorType::kAlpha_F16:        *load = SkRasterPipelineOp::load_af16;     break;
        case GrColorType::kRGBA_F16_Clamped: *load = SkRasterPipelineOp::load_f16;      break;
        case GrColorType::kRG_1616:          *load = SkRasterPipelineOp::load_rg1616;   break;
        case GrColorType::kRGBA_16161616:    *load = SkRasterPipelineOp::load_16161616; break;

        case GrColorType::kRGBA_8888_SRGB:   *load = SkRasterPipelineOp::load_8888;
                                             *isSRGB = true;
                                             break;
        case GrColorType::kRG_F16:           *load = SkRasterPipelineOp::load_rgf16;
                                             *isNormalized = false;
                                             break;
        case GrColorType::kRGBA_F16:         *load = SkRasterPipelineOp::load_f16;
                                             *isNormalized = false;
                                             break;
        case GrColorType::kRGBA_F32:         *load = SkRasterPipelineOp::load_f32;
                                             *isNormalized = false;
                                             break;
        case GrColorType::kAlpha_8xxx:       *load = SkRasterPipelineOp::load_8888;
                                             swizzle = skgpu::Swizzle("000r");
                                             break;
        case GrColorType::kAlpha_F32xxx:     *load = SkRasterPipelineOp::load_f32;
                                             swizzle = skgpu::Swizzle("000r");
                                             break;
        case GrColorType::kGray_8xxx:       *load = SkRasterPipelineOp::load_8888;
                                             swizzle = skgpu::Swizzle("rrr1");
                                             break;
        case GrColorType::kGray_8:           *load = SkRasterPipelineOp::load_a8;
                                             swizzle = skgpu::Swizzle("aaa1");
                                             break;
        case GrColorType::kR_8xxx:           *load = SkRasterPipelineOp::load_8888;
                                             swizzle = skgpu::Swizzle("r001");
                                             break;
        case GrColorType::kR_8:              *load = SkRasterPipelineOp::load_a8;
                                             swizzle = skgpu::Swizzle("a001");
                                             break;
        case GrColorType::kGrayAlpha_88:    *load = SkRasterPipelineOp::load_rg88;
                                             swizzle = skgpu::Swizzle("rrrg");
                                             break;
        case GrColorType::kBGRA_8888:        *load = SkRasterPipelineOp::load_8888;
                                             swizzle = skgpu::Swizzle("bgra");
                                             break;
        case GrColorType::kRGB_888x:         *load = SkRasterPipelineOp::load_8888;
                                             swizzle = skgpu::Swizzle("rgb1");
                                             break;

        // These are color types we don't expect to ever have to load.
        case GrColorType::kRGB_888:
        case GrColorType::kR_16:
        case GrColorType::kR_F16:
        case GrColorType::kGray_F16:
        case GrColorType::kUnknown:
            SK_ABORT("unexpected CT");
    }
    return swizzle;
}

enum class LumMode {
    kNone,
    kToRGB,
    kToAlpha
};

static skgpu::Swizzle get_dst_swizzle_and_store(GrColorType ct, SkRasterPipelineOp* store,
                                                LumMode* lumMode, bool* isNormalized,
                                                bool* isSRGB) {
    skgpu::Swizzle swizzle("rgba");
    *isNormalized = true;
    *isSRGB = false;
    *lumMode = LumMode::kNone;
    switch (ct) {
        case GrColorType::kAlpha_8:          *store = SkRasterPipelineOp::store_a8;       break;
        case GrColorType::kAlpha_16:         *store = SkRasterPipelineOp::store_a16;      break;
        case GrColorType::kBGR_565:          *store = SkRasterPipelineOp::store_565;      break;
        case GrColorType::kABGR_4444:        *store = SkRasterPipelineOp::store_4444;     break;
        case GrColorType::kARGB_4444:        swizzle = skgpu::Swizzle("bgra");
                                             *store = SkRasterPipelineOp::store_4444;     break;
        case GrColorType::kBGRA_4444:        swizzle = skgpu::Swizzle("argb");
                                             *store = SkRasterPipelineOp::store_4444;     break;
        case GrColorType::kRGBA_8888:        *store = SkRasterPipelineOp::store_8888;     break;
        case GrColorType::kRG_88:            *store = SkRasterPipelineOp::store_rg88;     break;
        case GrColorType::kRGBA_1010102:     *store = SkRasterPipelineOp::store_1010102;  break;
        case GrColorType::kBGRA_1010102:     swizzle = skgpu::Swizzle("bgra");
                                             *store = SkRasterPipelineOp::store_1010102;
                                             break;
        case GrColorType::kRGBA_F16_Clamped: *store = SkRasterPipelineOp::store_f16;      break;
        case GrColorType::kRG_1616:          *store = SkRasterPipelineOp::store_rg1616;   break;
        case GrColorType::kRGBA_16161616:    *store = SkRasterPipelineOp::store_16161616; break;

        case GrColorType::kRGBA_8888_SRGB:   *store = SkRasterPipelineOp::store_8888;
                                             *isSRGB = true;
                                             break;
        case GrColorType::kRG_F16:           *store = SkRasterPipelineOp::store_rgf16;
                                             *isNormalized = false;
                                             break;
        case GrColorType::kAlpha_F16:        *store = SkRasterPipelineOp::store_af16;
                                             *isNormalized = false;
                                             break;
        case GrColorType::kRGBA_F16:         *store = SkRasterPipelineOp::store_f16;
                                             *isNormalized = false;
                                             break;
        case GrColorType::kRGBA_F32:         *store = SkRasterPipelineOp::store_f32;
                                             *isNormalized = false;
                                             break;
        case GrColorType::kAlpha_8xxx:       *store = SkRasterPipelineOp::store_8888;
                                             swizzle = skgpu::Swizzle("a000");
                                             break;
        case GrColorType::kAlpha_F32xxx:     *store = SkRasterPipelineOp::store_f32;
                                             swizzle = skgpu::Swizzle("a000");
                                             break;
        case GrColorType::kBGRA_8888:        swizzle = skgpu::Swizzle("bgra");
                                             *store = SkRasterPipelineOp::store_8888;
                                             break;
        case GrColorType::kRGB_888x:         swizzle = skgpu::Swizzle("rgb1");
                                             *store = SkRasterPipelineOp::store_8888;
                                             break;
        case GrColorType::kR_8xxx:           swizzle = skgpu::Swizzle("r001");
                                             *store = SkRasterPipelineOp::store_8888;
                                             break;
        case GrColorType::kR_8:              swizzle = skgpu::Swizzle("agbr");
                                             *store = SkRasterPipelineOp::store_a8;
                                             break;
        case GrColorType::kR_16:             swizzle = skgpu::Swizzle("agbr");
                                             *store = SkRasterPipelineOp::store_a16;
                                             break;
        case GrColorType::kR_F16:            swizzle = skgpu::Swizzle("agbr");
                                             *store = SkRasterPipelineOp::store_af16;
                                             break;
        case GrColorType::kGray_F16:         *lumMode = LumMode::kToAlpha;
                                             *store = SkRasterPipelineOp::store_af16;
                                             break;
        case GrColorType::kGray_8:           *lumMode = LumMode::kToAlpha;
                                             *store = SkRasterPipelineOp::store_a8;
                                             break;
        case GrColorType::kGrayAlpha_88:     *lumMode = LumMode::kToRGB;
                                             swizzle = skgpu::Swizzle("ragb");
                                             *store = SkRasterPipelineOp::store_rg88;
                                             break;
        case GrColorType::kGray_8xxx:        *lumMode = LumMode::kToRGB;
                                             *store = SkRasterPipelineOp::store_8888;
                                             swizzle = skgpu::Swizzle("r000");
                                             break;

        // These are color types we don't expect to ever have to store.
        case GrColorType::kRGB_888:  // This is handled specially in GrConvertPixels.
        case GrColorType::kUnknown:
            SK_ABORT("unexpected CT");
    }
    return swizzle;
}

bool GrConvertPixels(const GrPixmap& dst, const GrCPixmap& src, bool flipY) {
    TRACE_EVENT0("skia.gpu", TRACE_FUNC);
    if (src.dimensions().isEmpty() || dst.dimensions().isEmpty()) {
        return false;
    }
    if (src.colorType() == GrColorType::kUnknown || dst.colorType() == GrColorType::kUnknown) {
        return false;
    }
    if (!src.hasPixels() || !dst.hasPixels()) {
        return false;
    }
    if (dst.dimensions() != src.dimensions()) {
        return false;
    }
    if (dst.colorType() == GrColorType::kRGB_888) {
        // SkRasterPipeline doesn't handle writing to RGB_888. So we have it write to RGB_888x and
        // then do another conversion that does the 24bit packing. We could be cleverer and skip the
        // temp pixmap if this is the only conversion but this is rare so keeping it simple.
        GrPixmap temp = GrPixmap::Allocate(dst.info().makeColorType(GrColorType::kRGB_888x));
        if (!GrConvertPixels(temp, src, flipY)) {
            return false;
        }
        auto* tRow = reinterpret_cast<const char*>(temp.addr());
        auto* dRow = reinterpret_cast<char*>(dst.addr());
        for (int y = 0; y < dst.height(); ++y, tRow += temp.rowBytes(), dRow += dst.rowBytes()) {
            for (int x = 0; x < dst.width(); ++x) {
                auto t = tRow + x*sizeof(uint32_t);
                auto d = dRow + x*3;
                memcpy(d, t, 3);
            }
        }
        return true;
    } else if (src.colorType() == GrColorType::kRGB_888) {
        // SkRasterPipeline doesn't handle reading from RGB_888. So convert it to RGB_888x and then
        // do a recursive call if there is any remaining conversion.
        GrPixmap temp = GrPixmap::Allocate(src.info().makeColorType(GrColorType::kRGB_888x));
        auto* sRow = reinterpret_cast<const char*>(src.addr());
        auto* tRow = reinterpret_cast<char*>(temp.addr());
        for (int y = 0; y < src.height(); ++y, sRow += src.rowBytes(), tRow += temp.rowBytes()) {
            for (int x = 0; x < src.width(); ++x) {
                auto s = sRow + x*3;
                auto t = tRow + x*sizeof(uint32_t);
                memcpy(t, s, 3);
                t[3] = static_cast<char>(0xFF);
            }
        }
        return GrConvertPixels(dst, temp, flipY);
    }

    size_t srcBpp = src.info().bpp();
    size_t dstBpp = dst.info().bpp();

    // SkRasterPipeline operates on row-pixels not row-bytes.
    SkASSERT(dst.rowBytes() % dstBpp == 0);
    SkASSERT(src.rowBytes() % srcBpp == 0);

    bool premul   = src.alphaType() == kUnpremul_SkAlphaType &&
                    dst.alphaType() == kPremul_SkAlphaType;
    bool unpremul = src.alphaType() == kPremul_SkAlphaType &&
                    dst.alphaType() == kUnpremul_SkAlphaType;
    bool alphaOrCSConversion =
            premul || unpremul || !SkColorSpace::Equals(src.colorSpace(), dst.colorSpace());

    if (src.colorType() == dst.colorType() && !alphaOrCSConversion) {
        size_t tightRB = dstBpp * dst.width();
        if (flipY) {
            auto s = static_cast<const char*>(src.addr());
            auto d = SkTAddOffset<char>(dst.addr(), dst.rowBytes()*(dst.height() - 1));
            for (int y = 0; y < dst.height(); ++y, d -= dst.rowBytes(), s += src.rowBytes()) {
                memcpy(d, s, tightRB);
            }
        } else {
            SkRectMemcpy(dst.addr(), dst.rowBytes(),
                         src.addr(), src.rowBytes(),
                         tightRB, src.height());
        }
        return true;
    }

    SkRasterPipelineOp load;
    bool srcIsNormalized;
    bool srcIsSRGB;
    auto loadSwizzle = get_load_and_src_swizzle(src.colorType(),
                                                &load,
                                                &srcIsNormalized,
                                                &srcIsSRGB);

    SkRasterPipelineOp store;
    LumMode lumMode;
    bool dstIsNormalized;
    bool dstIsSRGB;
    auto storeSwizzle = get_dst_swizzle_and_store(dst.colorType(),
                                                  &store,
                                                  &lumMode,
                                                  &dstIsNormalized,
                                                  &dstIsSRGB);

    SkTLazy<SkColorSpaceXformSteps> steps;
    skgpu::Swizzle loadStoreSwizzle;
    if (alphaOrCSConversion) {
        steps.init(src.colorSpace(), src.alphaType(), dst.colorSpace(), dst.alphaType());
    } else {
        loadStoreSwizzle = skgpu::Swizzle::Concat(loadSwizzle, storeSwizzle);
    }
    int cnt = 1;
    int height = src.height();
    SkRasterPipeline_MemoryCtx
            srcCtx{const_cast<void*>(src.addr()), SkToInt(src.rowBytes()/srcBpp)},
            dstCtx{                   dst.addr(), SkToInt(dst.rowBytes()/dstBpp)};

    if (flipY) {
        // It *almost* works to point the src at the last row and negate the stride and run the
        // whole rectangle. However, SkRasterPipeline::run()'s control loop uses size_t loop
        // variables so it winds up relying on unsigned overflow math. It works out in practice
        // but UBSAN says "no!" as it's technically undefined and in theory a compiler could emit
        // code that didn't do what is intended. So we go one row at a time. :(
        srcCtx.pixels = static_cast<char*>(srcCtx.pixels) + src.rowBytes()*(height - 1);
        std::swap(cnt, height);
    }

    bool hasConversion = alphaOrCSConversion || lumMode != LumMode::kNone;

    if (srcIsSRGB && dstIsSRGB && !hasConversion) {
        // No need to convert from srgb if we are just going to immediately convert it back.
        srcIsSRGB = dstIsSRGB = false;
    }

    hasConversion = hasConversion || srcIsSRGB || dstIsSRGB;

    SkRasterPipeline_<256> pipeline;
    pipeline.append(load, &srcCtx);
    if (hasConversion) {
        loadSwizzle.apply(&pipeline);
        if (srcIsSRGB) {
            pipeline.append_transfer_function(*skcms_sRGB_TransferFunction());
        }
        if (alphaOrCSConversion) {
            steps->apply(&pipeline);
        }
        switch (lumMode) {
            case LumMode::kNone:
                break;
            case LumMode::kToRGB:
                pipeline.append(SkRasterPipelineOp::bt709_luminance_or_luma_to_rgb);
                break;
            case LumMode::kToAlpha:
                pipeline.append(SkRasterPipelineOp::bt709_luminance_or_luma_to_alpha);
                // If we ever need to store srgb-encoded gray (e.g. GL_SLUMINANCE8) then we
                // should use ToRGB and then a swizzle stage rather than ToAlpha. The subsequent
                // transfer function stage ignores the alpha channel (where we just stashed the
                // gray).
                SkASSERT(!dstIsSRGB);
                break;
        }
        if (dstIsSRGB) {
            pipeline.append_transfer_function(*skcms_sRGB_Inverse_TransferFunction());
        }
        storeSwizzle.apply(&pipeline);
    } else {
        loadStoreSwizzle.apply(&pipeline);
    }
    pipeline.append(store, &dstCtx);
    auto pipelineFn = pipeline.compile();
    for (int i = 0; i < cnt; ++i) {
        pipelineFn(0, 0, src.width(), height);
        srcCtx.pixels = static_cast<char*>(srcCtx.pixels) - src.rowBytes();
        dstCtx.pixels = static_cast<char*>(dstCtx.pixels) + dst.rowBytes();
    }

    return true;
}

bool GrClearImage(const GrImageInfo& dstInfo, void* dst, size_t dstRB, std::array<float, 4> color) {
    TRACE_EVENT0("skia.gpu", TRACE_FUNC);

    if (!dstInfo.isValid()) {
        return false;
    }
    if (!dst) {
        return false;
    }
    if (dstRB < dstInfo.minRowBytes()) {
        return false;
    }
    if (dstInfo.colorType() == GrColorType::kRGB_888) {
        // SkRasterPipeline doesn't handle writing to RGB_888. So we handle that specially here.
        uint32_t rgba = SkColor4f{color[0], color[1], color[2], color[3]}.toBytes_RGBA();
        for (int y = 0; y < dstInfo.height(); ++y) {
            char* d = static_cast<char*>(dst) + y * dstRB;
            for (int x = 0; x < dstInfo.width(); ++x, d += 3) {
                memcpy(d, &rgba, 3);
            }
        }
        return true;
    }

    LumMode lumMode;
    bool isNormalized;
    bool dstIsSRGB;
    SkRasterPipelineOp store;
    skgpu::Swizzle storeSwizzle = get_dst_swizzle_and_store(dstInfo.colorType(), &store, &lumMode,
                                                            &isNormalized, &dstIsSRGB);
    char block[64];
    SkArenaAlloc alloc(block, sizeof(block), 1024);
    SkRasterPipeline_<256> pipeline;
    pipeline.append_constant_color(&alloc, color.data());
    switch (lumMode) {
        case LumMode::kNone:
            break;
        case LumMode::kToRGB:
            pipeline.append(SkRasterPipelineOp::bt709_luminance_or_luma_to_rgb);
            break;
        case LumMode::kToAlpha:
            pipeline.append(SkRasterPipelineOp::bt709_luminance_or_luma_to_alpha);
            // If we ever need to store srgb-encoded gray (e.g. GL_SLUMINANCE8) then we should use
            // ToRGB and then a swizzle stage rather than ToAlpha. The subsequent transfer function
            // stage ignores the alpha channel (where we just stashed the gray).
            SkASSERT(!dstIsSRGB);
            break;
    }
    if (dstIsSRGB) {
        pipeline.append_transfer_function(*skcms_sRGB_Inverse_TransferFunction());
    }
    storeSwizzle.apply(&pipeline);
    SkRasterPipeline_MemoryCtx dstCtx{dst, SkToInt(dstRB/dstInfo.bpp())};
    pipeline.append(store, &dstCtx);
    pipeline.run(0, 0, dstInfo.width(), dstInfo.height());

    return true;
}
