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

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTileMode.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkGradientShader.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "include/gpu/GrTypes.h"
#include "include/private/SkImageInfoPriv.h"
#include "include/private/SkTArray.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkConvertPixels.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDataUtils.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrPixmap.h"
#include "src/gpu/ganesh/GrSamplerState.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/SurfaceContext.h"
#include "src/gpu/ganesh/SurfaceFillContext.h"
#include "src/gpu/ganesh/effects/GrTextureEffect.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tests/TestUtils.h"
#include "tools/ToolUtils.h"
#include "tools/gpu/BackendSurfaceFactory.h"
#include "tools/gpu/BackendTextureImageFactory.h"

#include <algorithm>
#include <array>
#include <cstring>
#include <functional>
#include <initializer_list>
#include <memory>
#include <utility>
#include <vector>

struct GrContextOptions;

static constexpr int min_rgb_channel_bits(SkColorType ct) {
    switch (ct) {
        case kUnknown_SkColorType:            return 0;
        case kAlpha_8_SkColorType:            return 0;
        case kA16_unorm_SkColorType:          return 0;
        case kA16_float_SkColorType:          return 0;
        case kRGB_565_SkColorType:            return 5;
        case kARGB_4444_SkColorType:          return 4;
        case kR8G8_unorm_SkColorType:         return 8;
        case kR16G16_unorm_SkColorType:       return 16;
        case kR16G16_float_SkColorType:       return 16;
        case kRGBA_8888_SkColorType:          return 8;
        case kSRGBA_8888_SkColorType:         return 8;
        case kRGB_888x_SkColorType:           return 8;
        case kBGRA_8888_SkColorType:          return 8;
        case kRGBA_1010102_SkColorType:       return 10;
        case kRGB_101010x_SkColorType:        return 10;
        case kBGRA_1010102_SkColorType:       return 10;
        case kBGR_101010x_SkColorType:        return 10;
        case kGray_8_SkColorType:             return 8;   // counting gray as "rgb"
        case kRGBA_F16Norm_SkColorType:       return 10;  // just counting the mantissa
        case kRGBA_F16_SkColorType:           return 10;  // just counting the mantissa
        case kRGBA_F32_SkColorType:           return 23;  // just counting the mantissa
        case kR16G16B16A16_unorm_SkColorType: return 16;
        case kR8_unorm_SkColorType:           return 8;
    }
    SkUNREACHABLE;
}

static constexpr int alpha_channel_bits(SkColorType ct) {
    switch (ct) {
        case kUnknown_SkColorType:            return 0;
        case kAlpha_8_SkColorType:            return 8;
        case kA16_unorm_SkColorType:          return 16;
        case kA16_float_SkColorType:          return 16;
        case kRGB_565_SkColorType:            return 0;
        case kARGB_4444_SkColorType:          return 4;
        case kR8G8_unorm_SkColorType:         return 0;
        case kR16G16_unorm_SkColorType:       return 0;
        case kR16G16_float_SkColorType:       return 0;
        case kRGBA_8888_SkColorType:          return 8;
        case kSRGBA_8888_SkColorType:         return 8;
        case kRGB_888x_SkColorType:           return 0;
        case kBGRA_8888_SkColorType:          return 8;
        case kRGBA_1010102_SkColorType:       return 2;
        case kRGB_101010x_SkColorType:        return 0;
        case kBGRA_1010102_SkColorType:       return 2;
        case kBGR_101010x_SkColorType:        return 0;
        case kGray_8_SkColorType:             return 0;
        case kRGBA_F16Norm_SkColorType:       return 10;  // just counting the mantissa
        case kRGBA_F16_SkColorType:           return 10;  // just counting the mantissa
        case kRGBA_F32_SkColorType:           return 23;  // just counting the mantissa
        case kR16G16B16A16_unorm_SkColorType: return 16;
        case kR8_unorm_SkColorType:           return 0;
    }
    SkUNREACHABLE;
}

std::vector<SkIRect> make_long_rect_array(int w, int h) {
    return {
            // entire thing
            SkIRect::MakeWH(w, h),
            // larger on all sides
            SkIRect::MakeLTRB(-10, -10, w + 10, h + 10),
            // fully contained
            SkIRect::MakeLTRB(w/4, h/4, 3*w/4, 3*h/4),
            // outside top left
            SkIRect::MakeLTRB(-10, -10, -1, -1),
            // touching top left corner
            SkIRect::MakeLTRB(-10, -10, 0, 0),
            // overlapping top left corner
            SkIRect::MakeLTRB(-10, -10, w/4, h/4),
            // overlapping top left and top right corners
            SkIRect::MakeLTRB(-10, -10, w + 10, h/4),
            // touching entire top edge
            SkIRect::MakeLTRB(-10, -10, w + 10, 0),
            // overlapping top right corner
            SkIRect::MakeLTRB(3*w/4, -10, w + 10, h/4),
            // contained in x, overlapping top edge
            SkIRect::MakeLTRB(w/4, -10, 3*w/4, h/4),
            // outside top right corner
            SkIRect::MakeLTRB(w + 1, -10, w + 10, -1),
            // touching top right corner
            SkIRect::MakeLTRB(w, -10, w + 10, 0),
            // overlapping top left and bottom left corners
            SkIRect::MakeLTRB(-10, -10, w/4, h + 10),
            // touching entire left edge
            SkIRect::MakeLTRB(-10, -10, 0, h + 10),
            // overlapping bottom left corner
            SkIRect::MakeLTRB(-10, 3*h/4, w/4, h + 10),
            // contained in y, overlapping left edge
            SkIRect::MakeLTRB(-10, h/4, w/4, 3*h/4),
            // outside bottom left corner
            SkIRect::MakeLTRB(-10, h + 1, -1, h + 10),
            // touching bottom left corner
            SkIRect::MakeLTRB(-10, h, 0, h + 10),
            // overlapping bottom left and bottom right corners
            SkIRect::MakeLTRB(-10, 3*h/4, w + 10, h + 10),
            // touching entire left edge
            SkIRect::MakeLTRB(0, h, w, h + 10),
            // overlapping bottom right corner
            SkIRect::MakeLTRB(3*w/4, 3*h/4, w + 10, h + 10),
            // overlapping top right and bottom right corners
            SkIRect::MakeLTRB(3*w/4, -10, w + 10, h + 10),
    };
}

std::vector<SkIRect> make_short_rect_array(int w, int h) {
    return {
            // entire thing
            SkIRect::MakeWH(w, h),
            // fully contained
            SkIRect::MakeLTRB(w/4, h/4, 3*w/4, 3*h/4),
            // overlapping top right corner
            SkIRect::MakeLTRB(3*w/4, -10, w + 10, h/4),
    };
}

namespace {

struct GpuReadPixelTestRules {
    // Test unpremul sources? We could omit this and detect that creating the source of the read
    // failed but having it lets us skip generating reference color data.
    bool fAllowUnpremulSrc = true;
    // Are reads that are overlapping but not contained by the src bounds expected to succeed?
    bool fUncontainedRectSucceeds = true;
};

// Makes a src populated with the pixmap. The src should get its image info (or equivalent) from
// the pixmap.
template <typename T> using GpuSrcFactory = T(SkPixmap&);

enum class Result {
    kFail,
    kSuccess,
    kExcusedFailure,
};

// Does a read from the T into the pixmap.
template <typename T>
using GpuReadSrcFn = Result(const T&, const SkIPoint& offset, const SkPixmap&);

// Makes a dst for testing writes.
template <typename T> using GpuDstFactory = T(const SkImageInfo& ii);

// Does a write from the pixmap to the T.
template <typename T>
using GpuWriteDstFn = Result(const T&, const SkIPoint& offset, const SkPixmap&);

// To test the results of the write we do a read. This reads the entire src T. It should do a non-
// converting read (i.e. the image info of the returned pixmap matches that of the T).
template <typename T>
using GpuReadDstFn = SkAutoPixmapStorage(const T&);

}  // anonymous namespace

SkPixmap make_pixmap_have_valid_alpha_type(SkPixmap pm) {
    if (pm.alphaType() == kUnknown_SkAlphaType) {
        return {pm.info().makeAlphaType(kUnpremul_SkAlphaType), pm.addr(), pm.rowBytes()};
    }
    return pm;
}

static SkAutoPixmapStorage make_ref_data(const SkImageInfo& info, bool forceOpaque) {
    SkAutoPixmapStorage result;
    result.alloc(info);
    auto surface = SkSurface::MakeRasterDirect(make_pixmap_have_valid_alpha_type(result));
    if (!surface) {
        return result;
    }

    SkPoint pts1[] = {{0, 0}, {float(info.width()), float(info.height())}};
    static constexpr SkColor kColors1[] = {SK_ColorGREEN, SK_ColorRED};
    SkPaint paint;
    paint.setShader(SkGradientShader::MakeLinear(pts1, kColors1, nullptr, 2, SkTileMode::kClamp));
    surface->getCanvas()->drawPaint(paint);

    SkPoint pts2[] = {{float(info.width()), 0}, {0, float(info.height())}};
    static constexpr SkColor kColors2[] = {SK_ColorBLUE, SK_ColorBLACK};
    paint.setShader(SkGradientShader::MakeLinear(pts2, kColors2, nullptr, 2, SkTileMode::kClamp));
    paint.setBlendMode(SkBlendMode::kPlus);
    surface->getCanvas()->drawPaint(paint);

    // If not opaque add some fractional alpha.
    if (info.alphaType() != kOpaque_SkAlphaType && !forceOpaque) {
        static constexpr SkColor kColors3[] = {SK_ColorWHITE,
                                               SK_ColorWHITE,
                                               0x60FFFFFF,
                                               SK_ColorWHITE,
                                               SK_ColorWHITE};
        static constexpr SkScalar kPos3[] = {0.f, 0.15f, 0.5f, 0.85f, 1.f};
        paint.setShader(SkGradientShader::MakeRadial({info.width()/2.f, info.height()/2.f},
                                                     (info.width() + info.height())/10.f,
                                                     kColors3, kPos3, 5, SkTileMode::kMirror));
        paint.setBlendMode(SkBlendMode::kDstIn);
        surface->getCanvas()->drawPaint(paint);
    }
    return result;
};

template <typename T>
static void gpu_read_pixels_test_driver(skiatest::Reporter* reporter,
                                        const GpuReadPixelTestRules& rules,
                                        const std::function<GpuSrcFactory<T>>& srcFactory,
                                        const std::function<GpuReadSrcFn<T>>& read,
                                        SkString label) {
    if (!label.isEmpty()) {
        // Add space for printing.
        label.append(" ");
    }
    // Separate this out just to give it some line width to breathe. Note 'srcPixels' should have
    // the same image info as src. We will do a converting readPixels() on it to get the data
    // to compare with the results of 'read'.
    auto runTest = [&](const T& src,
                       const SkPixmap& srcPixels,
                       const SkImageInfo& readInfo,
                       SkIPoint offset) {
        const bool csConversion =
                !SkColorSpace::Equals(readInfo.colorSpace(), srcPixels.info().colorSpace());
        const auto readCT = readInfo.colorType();
        const auto readAT = readInfo.alphaType();
        const auto srcCT = srcPixels.info().colorType();
        const auto srcAT = srcPixels.info().alphaType();
        const auto rect = SkIRect::MakeWH(readInfo.width(), readInfo.height()).makeOffset(offset);
        const auto surfBounds = SkIRect::MakeWH(srcPixels.width(), srcPixels.height());
        const size_t readBpp = SkColorTypeBytesPerPixel(readCT);

        // Make the row bytes in the dst be loose for extra stress.
        const size_t dstRB = readBpp * readInfo.width() + 10 * readBpp;
        // This will make the last row tight.
        const size_t dstSize = readInfo.computeByteSize(dstRB);
        std::unique_ptr<char[]> dstData(new char[dstSize]);
        SkPixmap dstPixels(readInfo, dstData.get(), dstRB);
        // Initialize with an arbitrary value for each byte. Later we will check that only the
        // correct part of the destination gets overwritten by 'read'.
        static constexpr auto kInitialByte = static_cast<char>(0x1B);
        std::fill_n(static_cast<char*>(dstPixels.writable_addr()),
                    dstPixels.computeByteSize(),
                    kInitialByte);

        const Result result = read(src, offset, dstPixels);

        if (!SkIRect::Intersects(rect, surfBounds)) {
            REPORTER_ASSERT(reporter, result != Result::kSuccess);
        } else if (readCT == kUnknown_SkColorType) {
            REPORTER_ASSERT(reporter, result != Result::kSuccess);
        } else if ((readAT == kUnknown_SkAlphaType) != (srcAT == kUnknown_SkAlphaType)) {
            REPORTER_ASSERT(reporter, result != Result::kSuccess);
        } else if (!rules.fUncontainedRectSucceeds && !surfBounds.contains(rect)) {
            REPORTER_ASSERT(reporter, result != Result::kSuccess);
        } else if (result == Result::kFail) {
            // TODO: Support RGB/BGR 101010x, BGRA 1010102 on the GPU.
            if (SkColorTypeToGrColorType(readCT) != GrColorType::kUnknown) {
                ERRORF(reporter,
                       "Read failed. %sSrc CT: %s, Src AT: %s Read CT: %s, Read AT: %s, "
                       "Rect [%d, %d, %d, %d], CS conversion: %d\n",
                       label.c_str(),
                       ToolUtils::colortype_name(srcCT), ToolUtils::alphatype_name(srcAT),
                       ToolUtils::colortype_name(readCT), ToolUtils::alphatype_name(readAT),
                       rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, csConversion);
            }
            return result;
        }

        bool guardOk = true;
        auto guardCheck = [](char x) { return x == kInitialByte; };

        // Considering the rect we tried to read and the surface bounds figure  out which pixels in
        // both src and dst space should actually have been read and written.
        SkIRect srcReadRect;
        if (result == Result::kSuccess && srcReadRect.intersect(surfBounds, rect)) {
            SkIRect dstWriteRect = srcReadRect.makeOffset(-rect.fLeft, -rect.fTop);

            const bool lumConversion =
                    !(SkColorTypeChannelFlags(srcCT) & kGray_SkColorChannelFlag) &&
                    (SkColorTypeChannelFlags(readCT) & kGray_SkColorChannelFlag);
            // A CS or luminance conversion allows a 3 value difference and otherwise a 2 value
            // difference. Note that sometimes read back on GPU can be lossy even when there no
            // conversion at all because GPU->CPU read may go to a lower bit depth format and then
            // be promoted back to the original type. For example, GL ES cannot read to 1010102, so
            // we go through 8888.
            float numer = (lumConversion || csConversion) ? 3.f : 2.f;
            // Allow some extra tolerance if unpremuling.
            if (srcAT == kPremul_SkAlphaType && readAT == kUnpremul_SkAlphaType) {
                numer += 1;
            }
            int rgbBits = std::min({min_rgb_channel_bits(readCT), min_rgb_channel_bits(srcCT), 8});
            float tol = numer / (1 << rgbBits);
            float alphaTol = 0;
            if (readAT != kOpaque_SkAlphaType && srcAT != kOpaque_SkAlphaType) {
                // Alpha can also get squashed down to 8 bits going through an intermediate
                // color format.
                const int alphaBits = std::min({alpha_channel_bits(readCT),
                                                alpha_channel_bits(srcCT),
                                                8});
                alphaTol = 2.f / (1 << alphaBits);
            }

            const float tols[4] = {tol, tol, tol, alphaTol};
            auto error = std::function<ComparePixmapsErrorReporter>([&](int x, int y,
                                                                        const float diffs[4]) {
                SkASSERT(x >= 0 && y >= 0);
                ERRORF(reporter,
                       "%sSrc CT: %s, Src AT: %s, Read CT: %s, Read AT: %s, Rect [%d, %d, %d, %d]"
                       ", CS conversion: %d\n"
                       "Error at %d, %d. Diff in floats: (%f, %f, %f, %f)",
                       label.c_str(),
                       ToolUtils::colortype_name(srcCT), ToolUtils::alphatype_name(srcAT),
                       ToolUtils::colortype_name(readCT), ToolUtils::alphatype_name(readAT),
                       rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, csConversion, x, y,
                       diffs[0], diffs[1], diffs[2], diffs[3]);
            });
            SkAutoPixmapStorage ref;
            SkImageInfo refInfo = readInfo.makeDimensions(dstWriteRect.size());
            ref.alloc(refInfo);
            if (readAT == kUnknown_SkAlphaType) {
                // Do a spoofed read where src and dst alpha type are both kUnpremul. This will
                // allow SkPixmap readPixels to succeed and won't do any alpha type conversion.
                SkPixmap unpremulRef(refInfo.makeAlphaType(kUnpremul_SkAlphaType),
                                     ref.addr(),
                                     ref.rowBytes());
                SkPixmap unpremulSRc(srcPixels.info().makeAlphaType(kUnpremul_SkAlphaType),
                                     srcPixels.addr(),
                                     srcPixels.rowBytes());

                unpremulSRc.readPixels(unpremulRef, srcReadRect.x(), srcReadRect.y());
            } else {
                srcPixels.readPixels(ref, srcReadRect.x(), srcReadRect.y());
            }
            // This is the part of dstPixels that should have been updated.
            SkPixmap actual;
            SkAssertResult(dstPixels.extractSubset(&actual, dstWriteRect));
            ComparePixels(ref, actual, tols, error);

            const auto* v = dstData.get();
            const auto* end = dstData.get() + dstSize;
            guardOk = std::all_of(v, v + dstWriteRect.top() * dstPixels.rowBytes(), guardCheck);
            v += dstWriteRect.top() * dstPixels.rowBytes();
            for (int y = dstWriteRect.top(); y < dstWriteRect.bottom(); ++y) {
                guardOk |= std::all_of(v, v + dstWriteRect.left() * readBpp, guardCheck);
                auto pad = v + dstWriteRect.right() * readBpp;
                auto rowEnd = std::min(end, v + dstPixels.rowBytes());
                // min protects against reading past the end of the tight last row.
                guardOk |= std::all_of(pad, rowEnd, guardCheck);
                v = rowEnd;
            }
            guardOk |= std::all_of(v, end, guardCheck);
        } else {
            guardOk = std::all_of(dstData.get(), dstData.get() + dstSize, guardCheck);
        }
        if (!guardOk) {
            ERRORF(reporter,
                   "Result pixels modified result outside read rect [%d, %d, %d, %d]. "
                   "%sSrc CT: %s, Read CT: %s, CS conversion: %d",
                   rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, label.c_str(),
                   ToolUtils::colortype_name(srcCT), ToolUtils::colortype_name(readCT),
                   csConversion);
        }
        return result;
    };

    static constexpr int kW = 16;
    static constexpr int kH = 16;

    const std::vector<SkIRect> longRectArray = make_long_rect_array(kW, kH);
    const std::vector<SkIRect> shortRectArray = make_short_rect_array(kW, kH);

    // We ensure we use the long array once per src and read color type and otherwise use the
    // short array to improve test run time.
    // Also, some color types have no alpha values and thus Opaque Premul and Unpremul are
    // equivalent. Just ensure each redundant AT is tested once with each CT (src and read).
    // Similarly, alpha-only color types behave the same for all alpha types so just test premul
    // after one iter.
    // We consider a src or read CT thoroughly tested once it has run through the long rect array
    // and full complement of alpha types with one successful read in the loop.
    std::array<bool, kLastEnum_SkColorType + 1> srcCTTestedThoroughly  = {},
                                                readCTTestedThoroughly = {};
    for (int sat = 0; sat < kLastEnum_SkAlphaType; ++sat) {
        const auto srcAT = static_cast<SkAlphaType>(sat);
        if (srcAT == kUnpremul_SkAlphaType && !rules.fAllowUnpremulSrc) {
            continue;
        }
        for (int sct = 0; sct <= kLastEnum_SkColorType; ++sct) {
            const auto srcCT = static_cast<SkColorType>(sct);
            // We always make our ref data as F32
            auto refInfo = SkImageInfo::Make(kW, kH,
                                             kRGBA_F32_SkColorType,
                                             srcAT,
                                             SkColorSpace::MakeSRGB());
            // 1010102 formats have an issue where it's easy to make a resulting
            // color where r, g, or b is greater than a. CPU/GPU differ in whether the stored color
            // channels are clipped to the alpha value. CPU clips but GPU does not.
            // Note that we only currently use srcCT for the 1010102 workaround. If we remove this
            // we can also put the ref data setup above the srcCT loop.
            bool forceOpaque = srcAT == kPremul_SkAlphaType &&
                    (srcCT == kRGBA_1010102_SkColorType || srcCT == kBGRA_1010102_SkColorType);

            SkAutoPixmapStorage srcPixels = make_ref_data(refInfo, forceOpaque);
            auto src = srcFactory(srcPixels);
            if (!src) {
                continue;
            }
            if (SkColorTypeIsAlwaysOpaque(srcCT) && srcCTTestedThoroughly[srcCT] &&
                (kPremul_SkAlphaType == srcAT || kUnpremul_SkAlphaType == srcAT)) {
                continue;
            }
            if (SkColorTypeIsAlphaOnly(srcCT) && srcCTTestedThoroughly[srcCT] &&
                (kUnpremul_SkAlphaType == srcAT ||
                 kOpaque_SkAlphaType   == srcAT ||
                 kUnknown_SkAlphaType  == srcAT)) {
                continue;
            }
            for (int rct = 0; rct <= kLastEnum_SkColorType; ++rct) {
                const auto readCT = static_cast<SkColorType>(rct);
                for (const sk_sp<SkColorSpace>& readCS :
                     {SkColorSpace::MakeSRGB(), SkColorSpace::MakeSRGBLinear()}) {
                    for (int at = 0; at <= kLastEnum_SkAlphaType; ++at) {
                        const auto readAT = static_cast<SkAlphaType>(at);
                        if (srcAT != kOpaque_SkAlphaType && readAT == kOpaque_SkAlphaType) {
                            // This doesn't make sense.
                            continue;
                        }
                        if (SkColorTypeIsAlwaysOpaque(readCT) && readCTTestedThoroughly[readCT] &&
                            (kPremul_SkAlphaType == readAT || kUnpremul_SkAlphaType == readAT)) {
                            continue;
                        }
                        if (SkColorTypeIsAlphaOnly(readCT) && readCTTestedThoroughly[readCT] &&
                            (kUnpremul_SkAlphaType == readAT ||
                             kOpaque_SkAlphaType   == readAT ||
                             kUnknown_SkAlphaType  == readAT)) {
                            continue;
                        }
                        const auto& rects =
                                srcCTTestedThoroughly[sct] && readCTTestedThoroughly[rct]
                                        ? shortRectArray
                                        : longRectArray;
                        for (const auto& rect : rects) {
                            const auto readInfo = SkImageInfo::Make(rect.width(), rect.height(),
                                                                    readCT, readAT, readCS);
                            const SkIPoint offset = rect.topLeft();
                            Result r = runTest(src, srcPixels, readInfo, offset);
                            if (r == Result::kSuccess) {
                                srcCTTestedThoroughly[sct] = true;
                                readCTTestedThoroughly[rct] = true;
                            }
                        }
                    }
                }
            }
        }
    }
}

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SurfaceContextReadPixels,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    using Surface = std::unique_ptr<skgpu::v1::SurfaceContext>;
    GrDirectContext* direct = ctxInfo.directContext();
    auto reader = std::function<GpuReadSrcFn<Surface>>(
            [direct](const Surface& surface, const SkIPoint& offset, const SkPixmap& pixels) {
                if (surface->readPixels(direct, pixels, offset)) {
                    return Result::kSuccess;
                } else {
                    // Reading from a non-renderable format is not guaranteed to work on GL.
                    // We'd have to be able to force a copy or draw draw to a renderable format.
                    const auto& caps = *direct->priv().caps();
                    if (direct->backend() == GrBackendApi::kOpenGL &&
                        !caps.isFormatRenderable(surface->asSurfaceProxy()->backendFormat(), 1)) {
                        return Result::kExcusedFailure;
                    }
                    return Result::kFail;
                }
            });
    GpuReadPixelTestRules rules;
    rules.fAllowUnpremulSrc = true;
    rules.fUncontainedRectSucceeds = true;

    for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
        for (GrSurfaceOrigin origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
            auto factory = std::function<GpuSrcFactory<Surface>>(
                    [direct, origin, renderable](const SkPixmap& src) {
                        auto sc = CreateSurfaceContext(
                                direct, src.info(), SkBackingFit::kExact, origin, renderable);
                        if (sc) {
                            sc->writePixels(direct, src, {0, 0});
                        }
                        return sc;
                    });
            auto label = SkStringPrintf("Renderable: %d, Origin: %d", (int)renderable, origin);
            gpu_read_pixels_test_driver(reporter, rules, factory, reader, label);
        }
    }
}

DEF_GANESH_TEST_FOR_ALL_CONTEXTS(ReadPixels_InvalidRowBytes_Gpu,
                                 reporter,
                                 ctxInfo,
                                 CtsEnforcement::kApiLevel_T) {
    auto srcII = SkImageInfo::Make({10, 10}, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    auto surf = SkSurface::MakeRenderTarget(ctxInfo.directContext(), SkBudgeted::kYes, srcII);
    for (int ct = 0; ct < kLastEnum_SkColorType + 1; ++ct) {
        auto colorType = static_cast<SkColorType>(ct);
        size_t bpp = SkColorTypeBytesPerPixel(colorType);
        if (bpp <= 1) {
            continue;
        }
        auto dstII = srcII.makeColorType(colorType);
        size_t badRowBytes = (surf->width() + 1)*bpp - 1;
        auto storage = std::make_unique<char[]>(badRowBytes*surf->height());
        REPORTER_ASSERT(reporter, !surf->readPixels(dstII, storage.get(), badRowBytes, 0, 0));
    }
}

DEF_GANESH_TEST_FOR_ALL_CONTEXTS(WritePixels_InvalidRowBytes_Gpu,
                                 reporter,
                                 ctxInfo,
                                 CtsEnforcement::kApiLevel_T) {
    auto dstII = SkImageInfo::Make({10, 10}, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    auto surf = SkSurface::MakeRenderTarget(ctxInfo.directContext(), SkBudgeted::kYes, dstII);
    for (int ct = 0; ct < kLastEnum_SkColorType + 1; ++ct) {
        auto colorType = static_cast<SkColorType>(ct);
        size_t bpp = SkColorTypeBytesPerPixel(colorType);
        if (bpp <= 1) {
            continue;
        }
        auto srcII = dstII.makeColorType(colorType);
        size_t badRowBytes = (surf->width() + 1)*bpp - 1;
        auto storage = std::make_unique<char[]>(badRowBytes*surf->height());
        memset(storage.get(), 0, badRowBytes * surf->height());
        // SkSurface::writePixels doesn't report bool, SkCanvas's does.
        REPORTER_ASSERT(reporter,
                        !surf->getCanvas()->writePixels(srcII, storage.get(), badRowBytes, 0, 0));
    }
}

namespace {
struct AsyncContext {
    bool fCalled = false;
    std::unique_ptr<const SkImage::AsyncReadResult> fResult;
};
}  // anonymous namespace

// Making this a lambda in the test functions caused:
//   "error: cannot compile this forwarded non-trivially copyable parameter yet"
// on x86/Win/Clang bot, referring to 'result'.
static void async_callback(void* c, std::unique_ptr<const SkImage::AsyncReadResult> result) {
    auto context = static_cast<AsyncContext*>(c);
    context->fResult = std::move(result);
    context->fCalled = true;
};

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SurfaceAsyncReadPixels,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    using Surface = sk_sp<SkSurface>;
    auto reader = std::function<GpuReadSrcFn<Surface>>(
            [](const Surface& surface, const SkIPoint& offset, const SkPixmap& pixels) {
                auto direct = surface->recordingContext()->asDirectContext();
                SkASSERT(direct);

                AsyncContext context;
                auto rect = SkIRect::MakeSize(pixels.dimensions()).makeOffset(offset);

                // Rescale quality and linearity don't matter since we're doing a non-scaling
                // readback.
                surface->asyncRescaleAndReadPixels(pixels.info(), rect,
                                                   SkImage::RescaleGamma::kSrc,
                                                   SkImage::RescaleMode::kNearest,
                                                   async_callback, &context);
                direct->submit();
                while (!context.fCalled) {
                    direct->checkAsyncWorkCompletion();
                }
                if (!context.fResult) {
                    return Result::kFail;
                }
                SkRectMemcpy(pixels.writable_addr(), pixels.rowBytes(), context.fResult->data(0),
                             context.fResult->rowBytes(0), pixels.info().minRowBytes(),
                             pixels.height());
                return Result::kSuccess;
            });
    GpuReadPixelTestRules rules;
    rules.fAllowUnpremulSrc = false;
    rules.fUncontainedRectSucceeds = false;

    for (GrSurfaceOrigin origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
        auto factory = std::function<GpuSrcFactory<Surface>>(
                [context = ctxInfo.directContext(), origin](const SkPixmap& src) {
                    auto surf = SkSurface::MakeRenderTarget(context,
                                                            SkBudgeted::kYes,
                                                            src.info(),
                                                            1,
                                                            origin,
                                                            nullptr);
                    if (surf) {
                        surf->writePixels(src, 0, 0);
                    }
                    return surf;
                });
        auto label = SkStringPrintf("Origin: %d", origin);
        gpu_read_pixels_test_driver(reporter, rules, factory, reader, label);
        auto backendRTFactory = std::function<GpuSrcFactory<Surface>>(
                [context = ctxInfo.directContext(), origin](const SkPixmap& src) {
                    // Dawn backend implementation of backend render targets doesn't support
                    // reading.
                    if (context->backend() == GrBackendApi::kDawn) {
                        return Surface();
                    }
                    auto surf = sk_gpu_test::MakeBackendRenderTargetSurface(context,
                                                                            src.info(),
                                                                            origin,
                                                                            1);
                    if (surf) {
                        surf->writePixels(src, 0, 0);
                    }
                    return surf;
                });
        label = SkStringPrintf("BERT Origin: %d", origin);
        gpu_read_pixels_test_driver(reporter, rules, backendRTFactory, reader, label);
    }
}

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(ImageAsyncReadPixels,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    using Image = sk_sp<SkImage>;
    auto context = ctxInfo.directContext();
    auto reader = std::function<GpuReadSrcFn<Image>>([context](const Image& image,
                                                               const SkIPoint& offset,
                                                               const SkPixmap& pixels) {
        AsyncContext asyncContext;
        auto rect = SkIRect::MakeSize(pixels.dimensions()).makeOffset(offset);
        // The GPU implementation is based on rendering and will fail for non-renderable color
        // types.
        auto ct = SkColorTypeToGrColorType(image->colorType());
        auto format = context->priv().caps()->getDefaultBackendFormat(ct, GrRenderable::kYes);
        if (!context->priv().caps()->isFormatAsColorTypeRenderable(ct, format)) {
            return Result::kExcusedFailure;
        }

        // Rescale quality and linearity don't matter since we're doing a non-scaling readback.
        image->asyncRescaleAndReadPixels(pixels.info(), rect,
                                         SkImage::RescaleGamma::kSrc,
                                         SkImage::RescaleMode::kNearest,
                                         async_callback, &asyncContext);
        context->submit();
        while (!asyncContext.fCalled) {
            context->checkAsyncWorkCompletion();
        }
        if (!asyncContext.fResult) {
            return Result::kFail;
        }
        SkRectMemcpy(pixels.writable_addr(), pixels.rowBytes(), asyncContext.fResult->data(0),
                     asyncContext.fResult->rowBytes(0), pixels.info().minRowBytes(),
                     pixels.height());
        return Result::kSuccess;
    });

    GpuReadPixelTestRules rules;
    rules.fAllowUnpremulSrc = true;
    rules.fUncontainedRectSucceeds = false;

    for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
        for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
            auto factory = std::function<GpuSrcFactory<Image>>([&](const SkPixmap& src) {
                return sk_gpu_test::MakeBackendTextureImage(ctxInfo.directContext(), src,
                                                            renderable, origin);
            });
            auto label = SkStringPrintf("Renderable: %d, Origin: %d", (int)renderable, origin);
            gpu_read_pixels_test_driver(reporter, rules, factory, reader, label);
        }
    }
}

DEF_GANESH_TEST(AsyncReadPixelsContextShutdown, reporter, options, CtsEnforcement::kApiLevel_T) {
    const auto ii = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType,
                                      SkColorSpace::MakeSRGB());
    enum class ShutdownSequence {
        kFreeResult_DestroyContext,
        kDestroyContext_FreeResult,
        kFreeResult_ReleaseAndAbandon_DestroyContext,
        kFreeResult_Abandon_DestroyContext,
        kReleaseAndAbandon_FreeResult_DestroyContext,
        kAbandon_FreeResult_DestroyContext,
        kReleaseAndAbandon_DestroyContext_FreeResult,
        kAbandon_DestroyContext_FreeResult,
    };
    for (int t = 0; t < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++t) {
        auto type = static_cast<sk_gpu_test::GrContextFactory::ContextType>(t);
        for (auto sequence : {ShutdownSequence::kFreeResult_DestroyContext,
                              ShutdownSequence::kDestroyContext_FreeResult,
                              ShutdownSequence::kFreeResult_ReleaseAndAbandon_DestroyContext,
                              ShutdownSequence::kFreeResult_Abandon_DestroyContext,
                              ShutdownSequence::kReleaseAndAbandon_FreeResult_DestroyContext,
                              ShutdownSequence::kAbandon_FreeResult_DestroyContext,
                              ShutdownSequence::kReleaseAndAbandon_DestroyContext_FreeResult,
                              ShutdownSequence::kAbandon_DestroyContext_FreeResult}) {
            // Vulkan and D3D context abandoning without resource release has issues outside of the
            // scope of this test.
            if ((type == sk_gpu_test::GrContextFactory::kVulkan_ContextType ||
                 type == sk_gpu_test::GrContextFactory::kDirect3D_ContextType) &&
                (sequence == ShutdownSequence::kFreeResult_ReleaseAndAbandon_DestroyContext ||
                 sequence == ShutdownSequence::kFreeResult_Abandon_DestroyContext ||
                 sequence == ShutdownSequence::kReleaseAndAbandon_FreeResult_DestroyContext ||
                 sequence == ShutdownSequence::kReleaseAndAbandon_DestroyContext_FreeResult ||
                 sequence == ShutdownSequence::kAbandon_FreeResult_DestroyContext ||
                 sequence == ShutdownSequence::kAbandon_DestroyContext_FreeResult)) {
                continue;
            }
            for (bool yuv : {false, true}) {
                sk_gpu_test::GrContextFactory factory(options);
                auto direct = factory.get(type);
                if (!direct) {
                    continue;
                }
                // This test is only meaningful for contexts that support transfer buffers for
                // reads.
                if (!direct->priv().caps()->transferFromSurfaceToBufferSupport()) {
                    continue;
                }
                auto surf = SkSurface::MakeRenderTarget(direct, SkBudgeted::kYes, ii, 1, nullptr);
                if (!surf) {
                    continue;
                }
                AsyncContext cbContext;
                if (yuv) {
                    surf->asyncRescaleAndReadPixelsYUV420(
                            kIdentity_SkYUVColorSpace, SkColorSpace::MakeSRGB(), ii.bounds(),
                            ii.dimensions(), SkImage::RescaleGamma::kSrc,
                            SkImage::RescaleMode::kNearest, &async_callback, &cbContext);
                } else {
                    surf->asyncRescaleAndReadPixels(ii, ii.bounds(), SkImage::RescaleGamma::kSrc,
                                                    SkImage::RescaleMode::kNearest, &async_callback,
                                                    &cbContext);
                }
                direct->submit();
                while (!cbContext.fCalled) {
                    direct->checkAsyncWorkCompletion();
                }
                if (!cbContext.fResult) {
                    ERRORF(reporter, "Callback failed on %s. is YUV: %d",
                           sk_gpu_test::GrContextFactory::ContextTypeName(type), yuv);
                    continue;
                }
                // For vulkan we need to release all refs to the GrDirectContext before trying to
                // destroy the test context. The surface here is holding a ref.
                surf.reset();

                // The real test is that we don't crash, get Vulkan validation errors, etc, during
                // this shutdown sequence.
                switch (sequence) {
                    case ShutdownSequence::kFreeResult_DestroyContext:
                    case ShutdownSequence::kFreeResult_ReleaseAndAbandon_DestroyContext:
                    case ShutdownSequence::kFreeResult_Abandon_DestroyContext:
                        break;
                    case ShutdownSequence::kDestroyContext_FreeResult:
                        factory.destroyContexts();
                        break;
                    case ShutdownSequence::kReleaseAndAbandon_FreeResult_DestroyContext:
                        factory.releaseResourcesAndAbandonContexts();
                        break;
                    case ShutdownSequence::kAbandon_FreeResult_DestroyContext:
                        factory.abandonContexts();
                        break;
                    case ShutdownSequence::kReleaseAndAbandon_DestroyContext_FreeResult:
                        factory.releaseResourcesAndAbandonContexts();
                        factory.destroyContexts();
                        break;
                    case ShutdownSequence::kAbandon_DestroyContext_FreeResult:
                        factory.abandonContexts();
                        factory.destroyContexts();
                        break;
                }
                cbContext.fResult.reset();
                switch (sequence) {
                    case ShutdownSequence::kFreeResult_ReleaseAndAbandon_DestroyContext:
                        factory.releaseResourcesAndAbandonContexts();
                        break;
                    case ShutdownSequence::kFreeResult_Abandon_DestroyContext:
                        factory.abandonContexts();
                        break;
                    case ShutdownSequence::kFreeResult_DestroyContext:
                    case ShutdownSequence::kDestroyContext_FreeResult:
                    case ShutdownSequence::kReleaseAndAbandon_FreeResult_DestroyContext:
                    case ShutdownSequence::kAbandon_FreeResult_DestroyContext:
                    case ShutdownSequence::kReleaseAndAbandon_DestroyContext_FreeResult:
                    case ShutdownSequence::kAbandon_DestroyContext_FreeResult:
                        break;
                }
            }
        }
    }
}

template <typename T>
static void gpu_write_pixels_test_driver(skiatest::Reporter* reporter,
                                         const std::function<GpuDstFactory<T>>& dstFactory,
                                         const std::function<GpuWriteDstFn<T>>& write,
                                         const std::function<GpuReadDstFn<T>>& read) {
    // Separate this out just to give it some line width to breathe.
    auto runTest = [&](const T& dst,
                       const SkImageInfo& dstInfo,
                       const SkPixmap& srcPixels,
                       SkIPoint offset) {
        const bool csConversion =
                !SkColorSpace::Equals(dstInfo.colorSpace(), srcPixels.info().colorSpace());
        const auto writeCT = srcPixels.colorType();
        const auto writeAT = srcPixels.alphaType();
        const auto dstCT = dstInfo.colorType();
        const auto dstAT = dstInfo.alphaType();
        const auto rect = SkIRect::MakePtSize(offset, srcPixels.dimensions());
        const auto surfBounds = SkIRect::MakeSize(dstInfo.dimensions());

        // Do an initial read before the write.
        SkAutoPixmapStorage firstReadPM = read(dst);
        if (!firstReadPM.addr()) {
            // Particularly with GLES 2 we can have formats that are unreadable with our current
            // implementation of read pixels. If the format can't be attached to a FBO we don't have
            // a code path that draws it to another readable color type/format combo and reads from
            // that.
            return Result::kExcusedFailure;
        }

        const Result result = write(dst, offset, srcPixels);

        if (!SkIRect::Intersects(rect, surfBounds)) {
            REPORTER_ASSERT(reporter, result != Result::kSuccess);
        } else if (writeCT == kUnknown_SkColorType) {
            REPORTER_ASSERT(reporter, result != Result::kSuccess);
        } else if ((writeAT == kUnknown_SkAlphaType) != (dstAT == kUnknown_SkAlphaType)) {
            REPORTER_ASSERT(reporter, result != Result::kSuccess);
        } else if (result == Result::kExcusedFailure) {
            return result;
        } else if (result == Result::kFail) {
            // TODO: Support RGB/BGR 101010x, BGRA 1010102 on the GPU.
            if (SkColorTypeToGrColorType(writeCT) != GrColorType::kUnknown) {
                ERRORF(reporter,
                       "Write failed. Write CT: %s, Write AT: %s Dst CT: %s, Dst AT: %s, "
                       "Rect [%d, %d, %d, %d], CS conversion: %d\n",
                       ToolUtils::colortype_name(writeCT), ToolUtils::alphatype_name(writeAT),
                       ToolUtils::colortype_name(dstCT), ToolUtils::alphatype_name(dstAT),
                       rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, csConversion);
            }
            return result;
        }

        SkIRect checkRect;
        if (result != Result::kSuccess || !checkRect.intersect(surfBounds, rect)) {
            return result;
        }

        // Do an initial read before the write. We'll use this to verify that areas outside the
        // write are unaffected.
        SkAutoPixmapStorage secondReadPM = read(dst);
        if (!secondReadPM.addr()) {
            // The first read succeeded so this one should, too.
            ERRORF(reporter,
                   "could not read from dst (CT: %s, AT: %s)\n",
                   ToolUtils::colortype_name(dstCT),
                   ToolUtils::alphatype_name(dstAT));
            return Result::kFail;
        }

        // Sometimes wider types go through 8bit unorm intermediates because of API
        // restrictions.
        int rgbBits = std::min({min_rgb_channel_bits(writeCT), min_rgb_channel_bits(dstCT), 8});
        float tol = 2.f/(1 << rgbBits);
        float alphaTol = 0;
        if (writeAT != kOpaque_SkAlphaType && dstAT != kOpaque_SkAlphaType) {
            // Alpha can also get squashed down to 8 bits going through an intermediate
            // color format.
            const int alphaBits = std::min({alpha_channel_bits(writeCT),
                                            alpha_channel_bits(dstCT),
                                            8});
            alphaTol = 2.f/(1 << alphaBits);
        }

        const float tols[4] = {tol, tol, tol, alphaTol};
        auto error = std::function<ComparePixmapsErrorReporter>([&](int x,
                                                                    int y,
                                                                    const float diffs[4]) {
            SkASSERT(x >= 0 && y >= 0);
            ERRORF(reporter,
                   "Write CT: %s, Write AT: %s, Dst CT: %s, Dst AT: %s, Rect [%d, %d, %d, %d]"
                   ", CS conversion: %d\n"
                   "Error at %d, %d. Diff in floats: (%f, %f, %f, %f)",
                   ToolUtils::colortype_name(writeCT),
                   ToolUtils::alphatype_name(writeAT),
                   ToolUtils::colortype_name(dstCT),
                   ToolUtils::alphatype_name(dstAT),
                   rect.fLeft,
                   rect.fTop,
                   rect.fRight,
                   rect.fBottom,
                   csConversion,
                   x,
                   y,
                   diffs[0],
                   diffs[1],
                   diffs[2],
                   diffs[3]);
        });

        SkAutoPixmapStorage ref;
        ref.alloc(secondReadPM.info().makeDimensions(checkRect.size()));
        // Here we use the CPU backend to do the equivalent conversion as the write we're
        // testing, using kUnpremul instead of kUnknown since CPU requires a valid alpha type.
        SkAssertResult(make_pixmap_have_valid_alpha_type(srcPixels).readPixels(
                make_pixmap_have_valid_alpha_type(ref),
                std::max(0, -offset.fX),
                std::max(0, -offset.fY)));
        // This is the part of secondReadPixels that should have been updated by the write.
        SkPixmap actual;
        SkAssertResult(secondReadPM.extractSubset(&actual, checkRect));
        ComparePixels(ref, actual, tols, error);
        // The area around written rect should be the same in the first and second read.
        SkIRect borders[]{
                {               0,                 0, secondReadPM.width(), secondReadPM.height()},
                {checkRect.fRight,                 0,      checkRect.fLeft, secondReadPM.height()},
                { checkRect.fLeft,                 0,     checkRect.fRight,        checkRect.fTop},
                { checkRect.fLeft, checkRect.fBottom,     checkRect.fRight, secondReadPM.height()}
        };
        for (const auto r : borders) {
            if (!r.isEmpty()) {
                // Make a copy because MSVC for some reason doesn't correctly capture 'r'.
                SkIPoint tl = r.topLeft();
                auto guardError = std::function<ComparePixmapsErrorReporter>(
                        [&](int x, int y, const float diffs[4]) {
                            x += tl.x();
                            y += tl.y();
                            ERRORF(reporter,
                                   "Write CT: %s, Write AT: %s, Dst CT: %s, Dst AT: %s,"
                                   "Rect [%d, %d, %d, %d], CS conversion: %d\n"
                                   "Error in guard region %d, %d. Diff in floats: (%f, %f, %f, %f)",
                                   ToolUtils::colortype_name(writeCT),
                                   ToolUtils::alphatype_name(writeAT),
                                   ToolUtils::colortype_name(dstCT),
                                   ToolUtils::alphatype_name(dstAT),
                                   rect.fLeft,
                                   rect.fTop,
                                   rect.fRight,
                                   rect.fBottom,
                                   csConversion,
                                   x,
                                   y,
                                   diffs[0],
                                   diffs[1],
                                   diffs[2],
                                   diffs[3]);
                        });
                SkPixmap a, b;
                SkAssertResult(firstReadPM.extractSubset(&a, r));
                SkAssertResult(firstReadPM.extractSubset(&b, r));
                float zeroTols[4] = {};
                ComparePixels(a, b, zeroTols, guardError);
            }
        }
        return result;
    };

    static constexpr int kW = 16;
    static constexpr int kH = 16;

    const std::vector<SkIRect> longRectArray = make_long_rect_array(kW, kH);
    const std::vector<SkIRect> shortRectArray = make_short_rect_array(kW, kH);

    // We ensure we use the long array once per src and read color type and otherwise use the
    // short array to improve test run time.
    // Also, some color types have no alpha values and thus Opaque Premul and Unpremul are
    // equivalent. Just ensure each redundant AT is tested once with each CT (dst and write).
    // Similarly, alpha-only color types behave the same for all alpha types so just test premul
    // after one iter.
    // We consider a dst or write CT thoroughly tested once it has run through the long rect array
    // and full complement of alpha types with one successful read in the loop.
    std::array<bool, kLastEnum_SkColorType + 1> dstCTTestedThoroughly   = {},
                                                writeCTTestedThoroughly = {};
    for (int dat = 0; dat < kLastEnum_SkAlphaType; ++dat) {
        const auto dstAT = static_cast<SkAlphaType>(dat);
        for (int dct = 0; dct <= kLastEnum_SkColorType; ++dct) {
            const auto dstCT = static_cast<SkColorType>(dct);
            const auto dstInfo = SkImageInfo::Make(kW, kH, dstCT, dstAT, SkColorSpace::MakeSRGB());
            auto dst = dstFactory(dstInfo);
            if (!dst) {
                continue;
            }
            if (SkColorTypeIsAlwaysOpaque(dstCT) && dstCTTestedThoroughly[dstCT] &&
                (kPremul_SkAlphaType == dstAT || kUnpremul_SkAlphaType == dstAT)) {
                continue;
            }
            if (SkColorTypeIsAlphaOnly(dstCT) && dstCTTestedThoroughly[dstCT] &&
                (kUnpremul_SkAlphaType == dstAT ||
                 kOpaque_SkAlphaType   == dstAT ||
                 kUnknown_SkAlphaType  == dstAT)) {
                continue;
            }
            for (int wct = 0; wct <= kLastEnum_SkColorType; ++wct) {
                const auto writeCT = static_cast<SkColorType>(wct);
                for (const sk_sp<SkColorSpace>& writeCS : {SkColorSpace::MakeSRGB(),
                                                           SkColorSpace::MakeSRGBLinear()}) {
                    for (int wat = 0; wat <= kLastEnum_SkAlphaType; ++wat) {
                        const auto writeAT = static_cast<SkAlphaType>(wat);
                        if (writeAT != kOpaque_SkAlphaType && dstAT == kOpaque_SkAlphaType) {
                            // This doesn't make sense.
                            continue;
                        }
                        if (SkColorTypeIsAlwaysOpaque(writeCT) &&
                            writeCTTestedThoroughly[writeCT] &&
                            (kPremul_SkAlphaType == writeAT || kUnpremul_SkAlphaType == writeAT)) {
                            continue;
                        }
                        if (SkColorTypeIsAlphaOnly(writeCT) && writeCTTestedThoroughly[writeCT] &&
                            (kUnpremul_SkAlphaType == writeAT ||
                             kOpaque_SkAlphaType   == writeAT ||
                             kUnknown_SkAlphaType  == writeAT)) {
                            continue;
                        }
                        const auto& rects =
                                dstCTTestedThoroughly[dct] && writeCTTestedThoroughly[wct]
                                        ? shortRectArray
                                        : longRectArray;
                        for (const auto& rect : rects) {
                            auto writeInfo = SkImageInfo::Make(rect.size(),
                                                               writeCT,
                                                               writeAT,
                                                               writeCS);
                            // CPU and GPU handle 1010102 differently. CPU clamps RGB to A, GPU
                            // doesn't.
                            bool forceOpaque = writeCT == kRGBA_1010102_SkColorType ||
                                               writeCT == kBGRA_1010102_SkColorType;
                            SkAutoPixmapStorage writePixels = make_ref_data(writeInfo, forceOpaque);
                            const SkIPoint offset = rect.topLeft();
                            Result r = runTest(dst, dstInfo, writePixels, offset);
                            if (r == Result::kSuccess) {
                                dstCTTestedThoroughly[dct] = true;
                                writeCTTestedThoroughly[wct] = true;
                            }
                        }
                    }
                }
            }
        }
    }
}

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SurfaceContextWritePixels,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    using Surface = std::unique_ptr<skgpu::v1::SurfaceContext>;
    GrDirectContext* direct = ctxInfo.directContext();
    auto writer = std::function<GpuWriteDstFn<Surface>>(
            [direct](const Surface& surface, const SkIPoint& offset, const SkPixmap& pixels) {
                if (surface->writePixels(direct, pixels, offset)) {
                    return Result::kSuccess;
                } else {
                    return Result::kFail;
                }
            });
    auto reader = std::function<GpuReadDstFn<Surface>>([direct](const Surface& s) {
        SkAutoPixmapStorage result;
        auto grInfo = s->imageInfo();
        SkColorType ct = GrColorTypeToSkColorType(grInfo.colorType());
        SkASSERT(ct != kUnknown_SkColorType);
        auto skInfo = SkImageInfo::Make(grInfo.dimensions(), ct, grInfo.alphaType(),
                                        grInfo.refColorSpace());
        result.alloc(skInfo);
        if (!s->readPixels(direct, result, {0, 0})) {
            SkAutoPixmapStorage badResult;
            return badResult;
        }
        return result;
    });

    for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
        for (GrSurfaceOrigin origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
            auto factory = std::function<GpuDstFactory<Surface>>(
                    [direct, origin, renderable](const SkImageInfo& info) {
                        return CreateSurfaceContext(direct,
                                                    info,
                                                    SkBackingFit::kExact,
                                                    origin,
                                                    renderable);
                    });

            gpu_write_pixels_test_driver(reporter, factory, writer, reader);
        }
    }
}

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SurfaceContextWritePixelsMipped,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    auto direct = ctxInfo.directContext();
    if (!direct->priv().caps()->mipmapSupport()) {
        return;
    }
    static constexpr int kW = 25,
                         kH = 37;
    SkAutoPixmapStorage refP = make_ref_data(SkImageInfo::Make({kW, kH},
                                                               kRGBA_F32_SkColorType,
                                                               kPremul_SkAlphaType,
                                                               nullptr),
                                             false);
    SkAutoPixmapStorage refO = make_ref_data(SkImageInfo::Make({kW, kH},
                                                               kRGBA_F32_SkColorType,
                                                               kOpaque_SkAlphaType,
                                                               nullptr),
                                             true);

    for (int c = 0; c < kGrColorTypeCnt; ++c) {
        auto ct = static_cast<GrColorType>(c);
        // Below we use rendering to read the level pixels back.
        auto format = direct->priv().caps()->getDefaultBackendFormat(ct, GrRenderable::kYes);
        if (!format.isValid()) {
            continue;
        }
        SkAlphaType at = GrColorTypeHasAlpha(ct) ? kPremul_SkAlphaType : kOpaque_SkAlphaType;
        GrImageInfo info(ct, at, nullptr, kW, kH);
        SkTArray<GrCPixmap> levels;
        const auto& ref = at == kPremul_SkAlphaType ? refP : refO;
        for (int w = kW, h = kH; w || h; w/=2, h/=2) {
            auto level = GrPixmap::Allocate(info.makeWH(std::max(w, 1), std::max(h, 1)));
            SkPixmap src;
            SkAssertResult(ref.extractSubset(&src, SkIRect::MakeSize(level.dimensions())));
            SkAssertResult(GrConvertPixels(level, src));
            levels.push_back(level);
        }

        for (bool unowned : {false, true}) { // test a GrCPixmap that doesn't own its storage.
            for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
                for (GrSurfaceOrigin origin : {kTopLeft_GrSurfaceOrigin,
                                               kBottomLeft_GrSurfaceOrigin}) {
                    auto sc = CreateSurfaceContext(direct,
                                                   info,
                                                   SkBackingFit::kExact,
                                                   origin,
                                                   renderable,
                                                   /*sample count*/ 1,
                                                   GrMipmapped::kYes);
                    if (!sc) {
                        continue;
                    }
                    // Keeps pixels in unowned case alive until after writePixels is called but no
                    // longer.
                    GrPixmap keepAlive;
                    GrCPixmap savedLevel = levels[1];
                    if (unowned) {
                        // Also test non-tight row bytes with the unowned pixmap, bump width by 1.
                        int w = levels[1].width() + 1;
                        int h = levels[1].height();
                        keepAlive = GrPixmap::Allocate(levels[1].info().makeWH(w, h));
                        SkPixmap src;
                        // These pixel values will be the same as the original level 1.
                        SkAssertResult(ref.extractSubset(&src, SkIRect::MakeWH(w, h)));
                        SkAssertResult(GrConvertPixels(keepAlive, src));
                        levels[1] = GrCPixmap(levels[1].info(),
                                              keepAlive.addr(),
                                              keepAlive.rowBytes());
                    }
                    // Going through intermediate textures is not supported for MIP levels (because
                    // we don't support rendering to non-base levels). So it's hard to have any hard
                    // rules about when we expect success.
                    if (!sc->writePixels(direct, levels.begin(), levels.size())) {
                        continue;
                    }
                    // Make sure the pixels from the unowned pixmap are released and then put the
                    // original level back in for the comparison after the read below.
                    keepAlive = {};
                    levels[1] = savedLevel;

                    // TODO: Update this when read pixels supports reading back levels to read
                    // directly rather than using minimizing draws.
                    auto dstSC = CreateSurfaceContext(direct,
                                                      info,
                                                      SkBackingFit::kExact,
                                                      kBottomLeft_GrSurfaceOrigin,
                                                      GrRenderable::kYes);
                    SkASSERT(dstSC);
                    GrSamplerState sampler(SkFilterMode::kNearest, SkMipmapMode::kNearest);
                    for (int i = 1; i <= 1; ++i) {
                        auto te = GrTextureEffect::Make(sc->readSurfaceView(),
                                                        info.alphaType(),
                                                        SkMatrix::I(),
                                                        sampler,
                                                        *direct->priv().caps());
                        dstSC->asFillContext()->fillRectToRectWithFP(
                                SkIRect::MakeSize(sc->dimensions()),
                                SkIRect::MakeSize(levels[i].dimensions()),
                                std::move(te));
                        GrImageInfo readInfo =
                                dstSC->imageInfo().makeDimensions(levels[i].dimensions());
                        GrPixmap read = GrPixmap::Allocate(readInfo);
                        if (!dstSC->readPixels(direct, read, {0, 0})) {
                            continue;
                        }

                        auto skCT = GrColorTypeToSkColorType(info.colorType());
                        int rgbBits = std::min(min_rgb_channel_bits(skCT), 8);
                        float rgbTol = (rgbBits == 0) ? 1.f : 2.f / ((1 << rgbBits) - 1);
                        int alphaBits = std::min(alpha_channel_bits(skCT), 8);
                        float alphaTol = (alphaBits == 0) ? 1.f : 2.f / ((1 << alphaBits) - 1);
                        float tol[] = {rgbTol, rgbTol, rgbTol, alphaTol};

                        GrCPixmap a = levels[i];
                        GrCPixmap b = read;
                        // The compare code will linearize when reading the srgb data. This will
                        // magnify differences at the high end. Rather than adjusting the tolerance
                        // to compensate we do the comparison without going through srgb->linear.
                        if (ct == GrColorType::kRGBA_8888_SRGB) {
                            a = GrCPixmap(a.info().makeColorType(GrColorType::kRGBA_8888),
                                          a.addr(),
                                          a.rowBytes());
                            b = GrCPixmap(b.info().makeColorType(GrColorType::kRGBA_8888),
                                          b.addr(),
                                          b.rowBytes());
                        }

                        auto error = std::function<ComparePixmapsErrorReporter>(
                                [&](int x, int y, const float diffs[4]) {
                                    SkASSERT(x >= 0 && y >= 0);
                                    ERRORF(reporter,
                                           "CT: %s, Level %d, Unowned: %d. "
                                           "Error at %d, %d. Diff in floats:"
                                           "(%f, %f, %f, %f)",
                                           GrColorTypeToStr(info.colorType()), i, unowned, x, y,
                                           diffs[0], diffs[1], diffs[2], diffs[3]);
                                });
                        ComparePixels(a, b, tol, error);
                    }
                }
            }
        }
    }
}

// Tests a bug found in OOP-R canvas2d in Chrome. The GPU backend would incorrectly not bind
// buffer 0 to GL_PIXEL_PACK_BUFFER before a glReadPixels() that was supposed to read into
// client memory if a GrDirectContext::resetContext() occurred.
DEF_GANESH_TEST_FOR_GL_RENDERING_CONTEXTS(GLReadPixelsUnbindPBO,
                                          reporter,
                                          ctxInfo,
                                          CtsEnforcement::kApiLevel_T) {
    // Start with a async read so that we bind to GL_PIXEL_PACK_BUFFER.
    auto info = SkImageInfo::Make(16, 16, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    SkAutoPixmapStorage pmap = make_ref_data(info, /*forceOpaque=*/false);
    auto image = SkImage::MakeFromRaster(pmap, nullptr, nullptr);
    image = image->makeTextureImage(ctxInfo.directContext());
    if (!image) {
        ERRORF(reporter, "Couldn't make texture image.");
        return;
    }

    AsyncContext asyncContext;
    image->asyncRescaleAndReadPixels(info,
                                     SkIRect::MakeSize(info.dimensions()),
                                     SkImage::RescaleGamma::kSrc,
                                     SkImage::RescaleMode::kNearest,
                                     async_callback,
                                     &asyncContext);

    // This will force the async readback to finish.
    ctxInfo.directContext()->flushAndSubmit(true);
    if (!asyncContext.fCalled) {
        ERRORF(reporter, "async_callback not called.");
    }
    if (!asyncContext.fResult) {
        ERRORF(reporter, "async read failed.");
    }

    SkPixmap asyncResult(info, asyncContext.fResult->data(0), asyncContext.fResult->rowBytes(0));

    // Bug was that this would cause GrGLGpu to think no buffer was left bound to
    // GL_PIXEL_PACK_BUFFER even though async transfer did leave one bound. So the sync read
    // wouldn't bind buffer 0.
    ctxInfo.directContext()->resetContext();

    SkBitmap syncResult;
    syncResult.allocPixels(info);
    syncResult.eraseARGB(0xFF, 0xFF, 0xFF, 0xFF);

    image->readPixels(ctxInfo.directContext(), syncResult.pixmap(), 0, 0);

    float tol[4] = {};  // expect exactly same pixels, no conversions.
    auto error = std::function<ComparePixmapsErrorReporter>([&](int x, int y,
                                                                const float diffs[4]) {
      SkASSERT(x >= 0 && y >= 0);
      ERRORF(reporter, "Expect sync and async read to be the same. "
             "Error at %d, %d. Diff in floats: (%f, %f, %f, %f)",
             x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
    });

    ComparePixels(syncResult.pixmap(), asyncResult, tol, error);
}
