/*
 * 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/SkCanvas.h"
#include "include/core/SkImage.h"
#include "include/core/SkSurface.h"
#include "include/effects/SkGradientShader.h"
#include "include/gpu/GrDirectContext.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkConvertPixels.h"
#include "src/gpu/GrDirectContextPriv.h"
#include "src/gpu/GrImageInfo.h"
#include "src/gpu/GrSurfaceContext.h"
#include "src/gpu/GrSurfaceDrawContext.h"
#include "tests/Test.h"
#include "tests/TestUtils.h"
#include "tools/ToolUtils.h"
#include "tools/gpu/BackendSurfaceFactory.h"
#include "tools/gpu/BackendTextureImageFactory.h"
#include "tools/gpu/GrContextFactory.h"
#include "tools/gpu/ProxyUtils.h"

#include <initializer_list>

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 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;
    }
    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 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;
    }
    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_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceContextReadPixels, reporter, ctxInfo) {
    using Surface = std::unique_ptr<GrSurfaceContext>;
    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 surfContext = GrSurfaceContext::Make(
                                direct, src.info(), SkBackingFit::kExact, origin, renderable);
                        if (surfContext) {
                            surfContext->writePixels(direct, src, {0, 0});
                        }
                        return surfContext;
                    });
            auto label = SkStringPrintf("Renderable: %d, Origin: %d", (int)renderable, origin);
            gpu_read_pixels_test_driver(reporter, rules, factory, reader, label);
        }
    }
}

DEF_GPUTEST_FOR_ALL_CONTEXTS(ReadPixels_InvalidRowBytes_Gpu, reporter, ctxInfo) {
    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_GPUTEST_FOR_ALL_CONTEXTS(WritePixels_InvalidRowBytes_Gpu, reporter, ctxInfo) {
    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_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceAsyncReadPixels, reporter, ctxInfo) {
    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) {
                    // skbug.com/8862
                    if (src.colorType() == kRGB_888x_SkColorType) {
                        return Surface();
                    }
                    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_GPUTEST_FOR_RENDERING_CONTEXTS(ImageAsyncReadPixels, reporter, ctxInfo) {
    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) {
                // skbug.com/8862
                if (src.colorType() == kRGB_888x_SkColorType) {
                    return Image();
                }
                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_GPUTEST(AsyncReadPixelsContextShutdown, reporter, options) {
    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 context abandoning without resource release has issues outside of the scope of
            // this test.
            if (type == sk_gpu_test::GrContextFactory::kVulkan_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_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceContextWritePixels, reporter, ctxInfo) {
    using Surface = std::unique_ptr<GrSurfaceContext>;
    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 GrSurfaceContext::Make(direct,
                                                      info,
                                                      SkBackingFit::kExact,
                                                      origin,
                                                      renderable);
                    });

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

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfaceContextWritePixelsMipped, reporter, ctxInfo) {
    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);
        // skbug.com/8862
        if (ct == GrColorType::kRGB_888x) {
            continue;
        }
        // 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 = GrSurfaceContext::Make(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.count())) {
                        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 dst = GrSurfaceDrawContext::Make(direct,
                                                          info.colorType(),
                                                          info.refColorSpace(),
                                                          SkBackingFit::kExact,
                                                          info.dimensions());
                    SkASSERT(dst);
                    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());
                        dst->fillRectToRectWithFP(SkIRect::MakeSize(sc->dimensions()),
                                                  SkIRect::MakeSize(levels[i].dimensions()),
                                                  std::move(te));
                        GrImageInfo readInfo =
                                dst->imageInfo().makeDimensions(levels[i].dimensions());
                        GrPixmap read = GrPixmap::Allocate(readInfo);
                        if (!dst->readPixels(direct, read, {0, 0})) {
                            continue;
                        }

                        auto skCT = GrColorTypeToSkColorType(info.colorType());
                        int rgbBits = std::min(min_rgb_channel_bits(skCT), 8);
                        float rgbTol = 2.f / ((1 << rgbBits) - 1);
                        int alphaBits = std::min(alpha_channel_bits(skCT), 8);
                        float alphaTol = 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);
                    }
                }
            }
        }
    }
}
