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

#include "tests/Test.h"

#include "include/gpu/GrDirectContext.h"
#include "src/gpu/GrBitmapTextureMaker.h"
#include "src/gpu/GrClip.h"
#include "src/gpu/GrContextPriv.h"
#include "src/gpu/GrGpuResource.h"
#include "src/gpu/GrImageInfo.h"
#include "src/gpu/GrMemoryPool.h"
#include "src/gpu/GrProxyProvider.h"
#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
#include "src/gpu/GrResourceProvider.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ops/GrFillRectOp.h"
#include "src/gpu/ops/GrMeshDrawOp.h"
#include "tests/TestUtils.h"
#include <atomic>
#include <random>

namespace {
class TestOp : public GrMeshDrawOp {
public:
    DEFINE_OP_CLASS_ID
    static std::unique_ptr<GrDrawOp> Make(GrRecordingContext* rContext,
                                          std::unique_ptr<GrFragmentProcessor> fp) {
        GrOpMemoryPool* pool = rContext->priv().opMemoryPool();

        return pool->allocate<TestOp>(std::move(fp));
    }

    const char* name() const override { return "TestOp"; }

    void visitProxies(const VisitProxyFunc& func) const override {
        fProcessors.visitProxies(func);
    }

    FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }

    GrProcessorSet::Analysis finalize(
            const GrCaps& caps, const GrAppliedClip* clip, bool hasMixedSampledCoverage,
            GrClampType clampType) override {
        static constexpr GrProcessorAnalysisColor kUnknownColor;
        SkPMColor4f overrideColor;
        return fProcessors.finalize(
                kUnknownColor, GrProcessorAnalysisCoverage::kNone, clip,
                &GrUserStencilSettings::kUnused, hasMixedSampledCoverage, caps, clampType,
                &overrideColor);
    }

private:
    friend class ::GrOpMemoryPool; // for ctor

    TestOp(std::unique_ptr<GrFragmentProcessor> fp)
            : INHERITED(ClassID()), fProcessors(std::move(fp)) {
        this->setBounds(SkRect::MakeWH(100, 100), HasAABloat::kNo, IsHairline::kNo);
    }

    GrProgramInfo* programInfo() override { return nullptr; }
    void onCreateProgramInfo(const GrCaps*,
                             SkArenaAlloc*,
                             const GrSurfaceProxyView* writeView,
                             GrAppliedClip&&,
                             const GrXferProcessor::DstProxyView&) override { return; }
    void onPrePrepareDraws(GrRecordingContext*,
                           const GrSurfaceProxyView* writeView,
                           GrAppliedClip*,
                           const GrXferProcessor::DstProxyView&) override { return; }
    void onPrepareDraws(Target* target) override { return; }
    void onExecute(GrOpFlushState*, const SkRect&) override { return; }

    GrProcessorSet fProcessors;

    typedef GrMeshDrawOp INHERITED;
};

/**
 * FP used to test ref counts on owned GrGpuResources. Can also be a parent FP to test counts
 * of resources owned by child FPs.
 */
class TestFP : public GrFragmentProcessor {
public:
    static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> child) {
        return std::unique_ptr<GrFragmentProcessor>(new TestFP(std::move(child)));
    }
    static std::unique_ptr<GrFragmentProcessor> Make(const SkTArray<GrSurfaceProxyView>& views) {
        return std::unique_ptr<GrFragmentProcessor>(new TestFP(views));
    }

    const char* name() const override { return "test"; }

    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder* b) const override {
        static std::atomic<int32_t> nextKey{0};
        b->add32(nextKey++);
    }

    std::unique_ptr<GrFragmentProcessor> clone() const override {
        return std::unique_ptr<GrFragmentProcessor>(new TestFP(*this));
    }

private:
    TestFP(const SkTArray<GrSurfaceProxyView>& views)
            : INHERITED(kTestFP_ClassID, kNone_OptimizationFlags) {
        for (const GrSurfaceProxyView& view : views) {
            this->registerChild(GrTextureEffect::Make(view, kUnknown_SkAlphaType));
        }
    }

    TestFP(std::unique_ptr<GrFragmentProcessor> child)
            : INHERITED(kTestFP_ClassID, kNone_OptimizationFlags) {
        this->registerChild(std::move(child));
    }

    explicit TestFP(const TestFP& that) : INHERITED(kTestFP_ClassID, that.optimizationFlags()) {
        this->cloneAndRegisterAllChildProcessors(that);
    }

    virtual GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
        class TestGLSLFP : public GrGLSLFragmentProcessor {
        public:
            TestGLSLFP() {}
            void emitCode(EmitArgs& args) override {
                GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
                fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, args.fInputColor);
            }

        private:
        };
        return new TestGLSLFP();
    }

    bool onIsEqual(const GrFragmentProcessor&) const override { return false; }

    typedef GrFragmentProcessor INHERITED;
};
}  // namespace

DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
    auto context = ctxInfo.directContext();
    GrProxyProvider* proxyProvider = context->priv().proxyProvider();

    static constexpr SkISize kDims = {10, 10};

    const GrBackendFormat format =
        context->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
                                                        GrRenderable::kNo);
    GrSwizzle swizzle = context->priv().caps()->getReadSwizzle(format, GrColorType::kRGBA_8888);

    for (bool makeClone : {false, true}) {
        for (int parentCnt = 0; parentCnt < 2; parentCnt++) {
            auto renderTargetContext = GrRenderTargetContext::Make(
                    context, GrColorType::kRGBA_8888, nullptr, SkBackingFit::kApprox, {1, 1});
            {
                sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
                        format, kDims, GrRenderable::kNo, 1, GrMipmapped::kNo, SkBackingFit::kExact,
                        SkBudgeted::kYes, GrProtected::kNo);

                {
                    SkTArray<GrSurfaceProxyView> views;
                    views.push_back({proxy, kTopLeft_GrSurfaceOrigin, swizzle});
                    auto fp = TestFP::Make(std::move(views));
                    for (int i = 0; i < parentCnt; ++i) {
                        fp = TestFP::Make(std::move(fp));
                    }
                    std::unique_ptr<GrFragmentProcessor> clone;
                    if (makeClone) {
                        clone = fp->clone();
                    }
                    std::unique_ptr<GrDrawOp> op(TestOp::Make(context, std::move(fp)));
                    renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
                    if (clone) {
                        op = TestOp::Make(context, std::move(clone));
                        renderTargetContext->priv().testingOnly_addDrawOp(std::move(op));
                    }
                }

                // If the fp is cloned the number of refs should increase by one (for the clone)
                int expectedProxyRefs = makeClone ? 3 : 2;

                CheckSingleThreadedProxyRefs(reporter, proxy.get(), expectedProxyRefs, -1);

                context->flushAndSubmit();

                // just one from the 'proxy' sk_sp
                CheckSingleThreadedProxyRefs(reporter, proxy.get(), 1, 1);
            }
        }
    }
}

#include "tools/flags/CommandLineFlags.h"
static DEFINE_bool(randomProcessorTest, false,
                   "Use non-deterministic seed for random processor tests?");
static DEFINE_int(processorSeed, 0,
                  "Use specific seed for processor tests. Overridden by --randomProcessorTest.");

#if GR_TEST_UTILS

static GrColor input_texel_color(int i, int j, SkScalar delta) {
    // Delta must be less than 0.5 to prevent over/underflow issues with the input color
    SkASSERT(delta <= 0.5);

    SkColor color = SkColorSetARGB((uint8_t)(i & 0xFF),
                                   (uint8_t)(j & 0xFF),
                                   (uint8_t)((i + j) & 0xFF),
                                   (uint8_t)((2 * j - i) & 0xFF));
    SkColor4f color4f = SkColor4f::FromColor(color);
    // We only apply delta to the r,g, and b channels. This is because we're using this
    // to test the canTweakAlphaForCoverage() optimization. A processor is allowed
    // to use the input color's alpha in its calculation and report this optimization.
    for (int i = 0; i < 3; i++) {
        if (color4f[i] > 0.5) {
            color4f[i] -= delta;
        } else {
            color4f[i] += delta;
        }
    }
    return color4f.premul().toBytes_RGBA();
}

void test_draw_op(GrRecordingContext* rContext,
                  GrRenderTargetContext* rtc,
                  std::unique_ptr<GrFragmentProcessor> fp) {
    GrPaint paint;
    paint.setColorFragmentProcessor(std::move(fp));
    paint.setPorterDuffXPFactory(SkBlendMode::kSrc);

    auto op = GrFillRectOp::MakeNonAARect(rContext, std::move(paint), SkMatrix::I(),
                                          SkRect::MakeWH(rtc->width(), rtc->height()));
    rtc->priv().testingOnly_addDrawOp(std::move(op));
}

// The output buffer must be the same size as the render-target context.
void render_fp(GrDirectContext* dContext,
               GrRenderTargetContext* rtc,
               std::unique_ptr<GrFragmentProcessor> fp,
               GrColor* outBuffer) {
    test_draw_op(dContext, rtc, std::move(fp));
    std::fill_n(outBuffer, rtc->width() * rtc->height(), 0);
    rtc->readPixels(dContext, SkImageInfo::Make(rtc->width(), rtc->height(), kRGBA_8888_SkColorType,
                                      kPremul_SkAlphaType),
                    outBuffer, /*rowBytes=*/0, /*srcPt=*/{0, 0});
}

// This class is responsible for reproducibly generating a random fragment processor.
// An identical randomly-designed FP can be generated as many times as needed.
class TestFPGenerator {
    public:
        TestFPGenerator() = delete;
        TestFPGenerator(GrDirectContext* context, GrResourceProvider* resourceProvider)
                : fContext(context)
                , fResourceProvider(resourceProvider)
                , fInitialSeed(synthesizeInitialSeed())
                , fRandomSeed(fInitialSeed) {}

        uint32_t initialSeed() { return fInitialSeed; }

        bool init() {
            // Initializes the two test texture proxies that are available to the FP test factories.
            SkRandom random{fRandomSeed};
            static constexpr int kTestTextureSize = 256;

            {
                // Put premul data into the RGBA texture that the test FPs can optionally use.
                GrColor* rgbaData = new GrColor[kTestTextureSize * kTestTextureSize];
                for (int y = 0; y < kTestTextureSize; ++y) {
                    for (int x = 0; x < kTestTextureSize; ++x) {
                        rgbaData[kTestTextureSize * y + x] = input_texel_color(
                                random.nextULessThan(256), random.nextULessThan(256), 0.0f);
                    }
                }

                SkImageInfo ii = SkImageInfo::Make(kTestTextureSize, kTestTextureSize,
                                                   kRGBA_8888_SkColorType, kPremul_SkAlphaType);
                SkBitmap bitmap;
                bitmap.installPixels(
                        ii, rgbaData, ii.minRowBytes(),
                        [](void* addr, void* context) { delete[](GrColor*) addr; }, nullptr);
                bitmap.setImmutable();
                GrBitmapTextureMaker maker(fContext, bitmap,
                                           GrImageTexGenPolicy::kNew_Uncached_Budgeted);
                GrSurfaceProxyView view = maker.view(GrMipmapped::kNo);
                if (!view.proxy() || !view.proxy()->instantiate(fResourceProvider)) {
                    SkDebugf("Unable to instantiate RGBA8888 test texture.");
                    return false;
                }
                fTestViews[0] = GrProcessorTestData::ViewInfo{view, GrColorType::kRGBA_8888,
                                                              kPremul_SkAlphaType};
            }

            {
                // Put random values into the alpha texture that the test FPs can optionally use.
                uint8_t* alphaData = new uint8_t[kTestTextureSize * kTestTextureSize];
                for (int y = 0; y < kTestTextureSize; ++y) {
                    for (int x = 0; x < kTestTextureSize; ++x) {
                        alphaData[kTestTextureSize * y + x] = random.nextULessThan(256);
                    }
                }

                SkImageInfo ii = SkImageInfo::Make(kTestTextureSize, kTestTextureSize,
                                                   kAlpha_8_SkColorType, kPremul_SkAlphaType);
                SkBitmap bitmap;
                bitmap.installPixels(
                        ii, alphaData, ii.minRowBytes(),
                        [](void* addr, void* context) { delete[](uint8_t*) addr; }, nullptr);
                bitmap.setImmutable();
                GrBitmapTextureMaker maker(fContext, bitmap,
                                           GrImageTexGenPolicy::kNew_Uncached_Budgeted);
                GrSurfaceProxyView view = maker.view(GrMipmapped::kNo);
                if (!view.proxy() || !view.proxy()->instantiate(fResourceProvider)) {
                    SkDebugf("Unable to instantiate A8 test texture.");
                    return false;
                }
                fTestViews[1] = GrProcessorTestData::ViewInfo{view, GrColorType::kAlpha_8,
                                                              kPremul_SkAlphaType};
            }

            return true;
        }

        void reroll() {
            // Feed our current random seed into SkRandom to generate a new seed.
            SkRandom random{fRandomSeed};
            fRandomSeed = random.nextU();
        }

        std::unique_ptr<GrFragmentProcessor> make(int type, int randomTreeDepth,
                                                  std::unique_ptr<GrFragmentProcessor> inputFP) {
            // This will generate the exact same randomized FP (of each requested type) each time
            // it's called. Call `reroll` to get a different FP.
            SkRandom random{fRandomSeed};
            GrProcessorTestData testData{&random, fContext, randomTreeDepth,
                                         SK_ARRAY_COUNT(fTestViews), fTestViews,
                                         std::move(inputFP)};
            return GrFragmentProcessorTestFactory::MakeIdx(type, &testData);
        }

        std::unique_ptr<GrFragmentProcessor> make(int type, int randomTreeDepth,
                                                  GrSurfaceProxyView view,
                                                  SkAlphaType alpha = kPremul_SkAlphaType) {
            return make(type, randomTreeDepth, GrTextureEffect::Make(view, alpha));
        }

    private:
        static uint32_t synthesizeInitialSeed() {
            if (FLAGS_randomProcessorTest) {
                std::random_device rd;
                return rd();
            } else {
                return FLAGS_processorSeed;
            }
        }

        GrDirectContext* fContext;              // owned by caller
        GrResourceProvider* fResourceProvider;  // owned by caller
        const uint32_t fInitialSeed;
        uint32_t fRandomSeed;
        GrProcessorTestData::ViewInfo fTestViews[2];
};

// Creates a texture of premul colors used as the output of the fragment processor that precedes
// the fragment processor under test. Color values are those provided by input_texel_color().
GrSurfaceProxyView make_input_texture(GrRecordingContext* context, int width, int height,
                                      SkScalar delta) {
    GrColor* data = new GrColor[width * height];
    for (int y = 0; y < width; ++y) {
        for (int x = 0; x < height; ++x) {
            data[width * y + x] = input_texel_color(x, y, delta);
        }
    }

    SkImageInfo ii = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    SkBitmap bitmap;
    bitmap.installPixels(ii, data, ii.minRowBytes(),
                         [](void* addr, void* context) { delete[] (GrColor*)addr; }, nullptr);
    bitmap.setImmutable();
    GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
    return maker.view(GrMipmapped::kNo);
}

// We tag logged data as unpremul to avoid conversion when encoding as PNG. The input texture
// actually contains unpremul data. Also, even though we made the result data by rendering into
// a "unpremul" GrRenderTargetContext, our input texture is unpremul and outside of the random
// effect configuration, we didn't do anything to ensure the output is actually premul. We just
// don't currently allow kUnpremul GrRenderTargetContexts.
static constexpr auto kLogAlphaType = kUnpremul_SkAlphaType;

bool log_pixels(GrColor* pixels, int widthHeight, SkString* dst) {
    SkImageInfo info =
            SkImageInfo::Make(widthHeight, widthHeight, kRGBA_8888_SkColorType, kLogAlphaType);
    SkBitmap bmp;
    bmp.installPixels(info, pixels, widthHeight * sizeof(GrColor));
    return BipmapToBase64DataURI(bmp, dst);
}

bool log_texture_view(GrDirectContext* dContext, GrSurfaceProxyView src, SkString* dst) {
    SkImageInfo ii = SkImageInfo::Make(src.proxy()->dimensions(), kRGBA_8888_SkColorType,
                                       kLogAlphaType);

    auto sContext = GrSurfaceContext::Make(dContext, std::move(src), GrColorType::kRGBA_8888,
                                           kLogAlphaType, nullptr);
    SkBitmap bm;
    SkAssertResult(bm.tryAllocPixels(ii));
    SkAssertResult(sContext->readPixels(dContext, ii, bm.getPixels(), bm.rowBytes(), {0, 0}));
    return BipmapToBase64DataURI(bm, dst);
}

bool fuzzy_color_equals(const SkPMColor4f& c1, const SkPMColor4f& c2) {
    // With the loss of precision of rendering into 32-bit color, then estimating the FP's output
    // from that, it is not uncommon for a valid output to differ from estimate by up to 0.01
    // (really 1/128 ~ .0078, but frequently floating point issues make that tolerance a little
    // too unforgiving).
    static constexpr SkScalar kTolerance = 0.01f;
    for (int i = 0; i < 4; i++) {
        if (!SkScalarNearlyEqual(c1[i], c2[i], kTolerance)) {
            return false;
        }
    }
    return true;
}

// Given three input colors (color preceding the FP being tested) provided to the FP at the same
// local coord and the three corresponding FP outputs, this ensures that either:
//   out[0] = fp * in[0].a, out[1] = fp * in[1].a, and out[2] = fp * in[2].a
// where fp is the pre-modulated color that should not be changing across frames (FP's state doesn't
// change), OR:
//   out[0] = fp * in[0], out[1] = fp * in[1], and out[2] = fp * in[2]
// (per-channel modulation instead of modulation by just the alpha channel)
// It does this by estimating the pre-modulated fp color from one of the input/output pairs and
// confirms the conditions hold for the other two pairs.
// It is required that the three input colors have the same alpha as fp is allowed to be a function
// of the input alpha (but not r, g, or b).
bool legal_modulation(const GrColor in[3], const GrColor out[3]) {
    // Convert to floating point, which is the number space the FP operates in (more or less)
    SkPMColor4f inf[3], outf[3];
    for (int i = 0; i < 3; ++i) {
        inf[i]  = SkPMColor4f::FromBytes_RGBA(in[i]);
        outf[i] = SkPMColor4f::FromBytes_RGBA(out[i]);
    }
    // This test is only valid if all the input alphas are the same.
    SkASSERT(inf[0].fA == inf[1].fA && inf[1].fA == inf[2].fA);

    // Reconstruct the output of the FP before the shader modulated its color with the input value.
    // When the original input is very small, it may cause the final output color to round
    // to 0, in which case we estimate the pre-modulated color using one of the stepped frames that
    // will then have a guaranteed larger channel value (since the offset will be added to it).
    SkPMColor4f fpPreColorModulation = {0,0,0,0};
    SkPMColor4f fpPreAlphaModulation = {0,0,0,0};
    for (int i = 0; i < 4; i++) {
        // Use the most stepped up frame
        int maxInIdx = inf[0][i] > inf[1][i] ? 0 : 1;
        maxInIdx = inf[maxInIdx][i] > inf[2][i] ? maxInIdx : 2;
        const SkPMColor4f& in = inf[maxInIdx];
        const SkPMColor4f& out = outf[maxInIdx];
        if (in[i] > 0) {
            fpPreColorModulation[i] = out[i] / in[i];
        }
        if (in[3] > 0) {
            fpPreAlphaModulation[i] = out[i] / in[3];
        }
    }

    // With reconstructed pre-modulated FP output, derive the expected value of fp * input for each
    // of the transformed input colors.
    SkPMColor4f expectedForAlphaModulation[3];
    SkPMColor4f expectedForColorModulation[3];
    for (int i = 0; i < 3; ++i) {
        expectedForAlphaModulation[i] = fpPreAlphaModulation * inf[i].fA;
        expectedForColorModulation[i] = fpPreColorModulation * inf[i];
        // If the input alpha is 0 then the other channels should also be zero
        // since the color is assumed to be premul. Modulating zeros by anything
        // should produce zeros.
        if (inf[i].fA == 0) {
            SkASSERT(inf[i].fR == 0 && inf[i].fG == 0 && inf[i].fB == 0);
            expectedForColorModulation[i] = expectedForAlphaModulation[i] = {0, 0, 0, 0};
        }
    }

    bool isLegalColorModulation = fuzzy_color_equals(outf[0], expectedForColorModulation[0]) &&
                                  fuzzy_color_equals(outf[1], expectedForColorModulation[1]) &&
                                  fuzzy_color_equals(outf[2], expectedForColorModulation[2]);

    bool isLegalAlphaModulation = fuzzy_color_equals(outf[0], expectedForAlphaModulation[0]) &&
                                  fuzzy_color_equals(outf[1], expectedForAlphaModulation[1]) &&
                                  fuzzy_color_equals(outf[2], expectedForAlphaModulation[2]);

    // This can be enabled to print the values that caused this check to fail.
    if (0 && !isLegalColorModulation && !isLegalAlphaModulation) {
        SkDebugf("Color modulation test\n\timplied mod color: (%.03f, %.03f, %.03f, %.03f)\n",
                 fpPreColorModulation[0],
                 fpPreColorModulation[1],
                 fpPreColorModulation[2],
                 fpPreColorModulation[3]);
        for (int i = 0; i < 3; ++i) {
            SkDebugf("\t(%.03f, %.03f, %.03f, %.03f) -> "
                     "(%.03f, %.03f, %.03f, %.03f) | "
                     "(%.03f, %.03f, %.03f, %.03f), ok: %d\n",
                     inf[i].fR, inf[i].fG, inf[i].fB, inf[i].fA,
                     outf[i].fR, outf[i].fG, outf[i].fB, outf[i].fA,
                     expectedForColorModulation[i].fR, expectedForColorModulation[i].fG,
                     expectedForColorModulation[i].fB, expectedForColorModulation[i].fA,
                     fuzzy_color_equals(outf[i], expectedForColorModulation[i]));
        }
        SkDebugf("Alpha modulation test\n\timplied mod color: (%.03f, %.03f, %.03f, %.03f)\n",
                 fpPreAlphaModulation[0],
                 fpPreAlphaModulation[1],
                 fpPreAlphaModulation[2],
                 fpPreAlphaModulation[3]);
        for (int i = 0; i < 3; ++i) {
            SkDebugf("\t(%.03f, %.03f, %.03f, %.03f) -> "
                     "(%.03f, %.03f, %.03f, %.03f) | "
                     "(%.03f, %.03f, %.03f, %.03f), ok: %d\n",
                     inf[i].fR, inf[i].fG, inf[i].fB, inf[i].fA,
                     outf[i].fR, outf[i].fG, outf[i].fB, outf[i].fA,
                     expectedForAlphaModulation[i].fR, expectedForAlphaModulation[i].fG,
                     expectedForAlphaModulation[i].fB, expectedForAlphaModulation[i].fA,
                     fuzzy_color_equals(outf[i], expectedForAlphaModulation[i]));
        }
    }
    return isLegalColorModulation || isLegalAlphaModulation;
}

DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ProcessorOptimizationValidationTest, reporter, ctxInfo) {
    GrDirectContext* context = ctxInfo.directContext();
    GrResourceProvider* resourceProvider = context->priv().resourceProvider();
    using FPFactory = GrFragmentProcessorTestFactory;

    TestFPGenerator fpGenerator{context, resourceProvider};
    if (!fpGenerator.init()) {
        ERRORF(reporter, "Could not initialize TestFPGenerator");
        return;
    }

    // Make the destination context for the test.
    static constexpr int kRenderSize = 256;
    auto rtc = GrRenderTargetContext::Make(
            context, GrColorType::kRGBA_8888, nullptr, SkBackingFit::kExact,
            {kRenderSize, kRenderSize});

    // Coverage optimization uses three frames with a linearly transformed input texture.  The first
    // frame has no offset, second frames add .2 and .4, which should then be present as a fixed
    // difference between the frame outputs if the FP is properly following the modulation
    // requirements of the coverage optimization.
    static constexpr SkScalar kInputDelta = 0.2f;
    GrSurfaceProxyView inputTexture1 = make_input_texture(context, kRenderSize, kRenderSize, 0.0f);
    GrSurfaceProxyView inputTexture2 = make_input_texture(context, kRenderSize, kRenderSize,
                                                          kInputDelta);
    GrSurfaceProxyView inputTexture3 = make_input_texture(context, kRenderSize, kRenderSize,
                                                          2 * kInputDelta);

    // Encoded images are very verbose and this tests many potential images, so only export the
    // first failure (subsequent failures have a reasonable chance of being related).
    bool loggedFirstFailure = false;
    bool loggedFirstWarning = false;

    // Storage for the three frames required for coverage compatibility optimization testing.
    // Each frame uses the correspondingly numbered inputTextureX.
    std::vector<GrColor> readData1(kRenderSize * kRenderSize);
    std::vector<GrColor> readData2(kRenderSize * kRenderSize);
    std::vector<GrColor> readData3(kRenderSize * kRenderSize);

    // Because processor factories configure themselves in random ways, this is not exhaustive.
    for (int i = 0; i < FPFactory::Count(); ++i) {
        int optimizedForOpaqueInput = 0;
        int optimizedForCoverageAsAlpha = 0;
        int optimizedForConstantOutputForInput = 0;

#ifdef __MSVC_RUNTIME_CHECKS
        // This test is infuriatingly slow with MSVC runtime checks enabled
        static constexpr int kMinimumTrials = 1;
        static constexpr int kMaximumTrials = 1;
        static constexpr int kExpectedSuccesses = 1;
#else
        // We start by testing each fragment-processor 100 times, watching the optimization bits
        // that appear. If we see an optimization bit appear in those first 100 trials, we keep
        // running tests until we see at least five successful trials that have this optimization
        // bit enabled. If we never see a particular optimization bit after 100 trials, we assume
        // that this FP doesn't support that optimization at all.
        static constexpr int kMinimumTrials = 100;
        static constexpr int kMaximumTrials = 2000;
        static constexpr int kExpectedSuccesses = 5;
#endif

        for (int trial = 0;; ++trial) {
            // Create a randomly-configured FP.
            fpGenerator.reroll();
            std::unique_ptr<GrFragmentProcessor> fp =
                    fpGenerator.make(i, /*randomTreeDepth=*/1, inputTexture1);

            // If we have iterated enough times and seen a sufficient number of successes on each
            // optimization bit that can be returned, stop running trials.
            if (trial >= kMinimumTrials) {
                bool moreTrialsNeeded = (optimizedForOpaqueInput > 0 &&
                                         optimizedForOpaqueInput < kExpectedSuccesses) ||
                                        (optimizedForCoverageAsAlpha > 0 &&
                                         optimizedForCoverageAsAlpha < kExpectedSuccesses) ||
                                        (optimizedForConstantOutputForInput > 0 &&
                                         optimizedForConstantOutputForInput < kExpectedSuccesses);
                if (!moreTrialsNeeded) break;

                if (trial >= kMaximumTrials) {
                    SkDebugf("Abandoning ProcessorOptimizationValidationTest after %d trials. "
                             "Seed: 0x%08x, processor: %s.",
                             kMaximumTrials, fpGenerator.initialSeed(), fp->name());
                    break;
                }
            }

            // Skip further testing if this trial has no optimization bits enabled.
            if (!fp->hasConstantOutputForConstantInput() && !fp->preservesOpaqueInput() &&
                !fp->compatibleWithCoverageAsAlpha()) {
                continue;
            }

            // We can make identical copies of the test FP in order to test coverage-as-alpha.
            if (fp->compatibleWithCoverageAsAlpha()) {
                // Create and render two identical versions of this FP, but using different input
                // textures, to check coverage optimization. We don't need to do this step for
                // constant-output or preserving-opacity tests.
                render_fp(context, rtc.get(),
                          fpGenerator.make(i, /*randomTreeDepth=*/1, inputTexture2),
                          readData2.data());
                render_fp(context, rtc.get(),
                          fpGenerator.make(i, /*randomTreeDepth=*/1, inputTexture3),
                          readData3.data());
                ++optimizedForCoverageAsAlpha;
            }

            if (fp->hasConstantOutputForConstantInput()) {
                ++optimizedForConstantOutputForInput;
            }

            if (fp->preservesOpaqueInput()) {
                ++optimizedForOpaqueInput;
            }

            // Draw base frame last so that rtc holds the original FP behavior if we need to dump
            // the image to the log.
            render_fp(context, rtc.get(), fpGenerator.make(i, /*randomTreeDepth=*/1, inputTexture1),
                      readData1.data());

            // This test has a history of being flaky on a number of devices. If an FP is logically
            // violating the optimizations, it's reasonable to expect it to violate requirements on
            // a large number of pixels in the image. Sporadic pixel violations are more indicative
            // of device errors and represents a separate problem.
#if defined(SK_BUILD_FOR_SKQP)
            static constexpr int kMaxAcceptableFailedPixels = 0; // Strict when running as SKQP
#else
            static constexpr int kMaxAcceptableFailedPixels = 2 * kRenderSize; // ~0.7% of the image
#endif

            // Collect first optimization failure message, to be output later as a warning or an
            // error depending on whether the rendering "passed" or failed.
            int failedPixelCount = 0;
            SkString coverageMessage;
            SkString opaqueMessage;
            SkString constMessage;
            for (int y = 0; y < kRenderSize; ++y) {
                for (int x = 0; x < kRenderSize; ++x) {
                    bool passing = true;
                    GrColor input = input_texel_color(x, y, 0.0f);
                    GrColor output = readData1[y * kRenderSize + x];

                    if (fp->compatibleWithCoverageAsAlpha()) {
                        GrColor ins[3];
                        ins[0] = input;
                        ins[1] = input_texel_color(x, y, kInputDelta);
                        ins[2] = input_texel_color(x, y, 2 * kInputDelta);

                        GrColor outs[3];
                        outs[0] = output;
                        outs[1] = readData2[y * kRenderSize + x];
                        outs[2] = readData3[y * kRenderSize + x];

                        if (!legal_modulation(ins, outs)) {
                            passing = false;
                            if (coverageMessage.isEmpty()) {
                                coverageMessage.printf(
                                        "\"Modulating\" processor %s did not match "
                                        "alpha-modulation nor color-modulation rules. "
                                        "Input: 0x%08x, Output: 0x%08x, pixel (%d, %d).",
                                        fp->name(), input, output, x, y);
                            }
                        }
                    }

                    SkPMColor4f input4f = SkPMColor4f::FromBytes_RGBA(input);
                    SkPMColor4f output4f = SkPMColor4f::FromBytes_RGBA(output);
                    SkPMColor4f expected4f;
                    if (fp->hasConstantOutputForConstantInput(input4f, &expected4f)) {
                        float rDiff = fabsf(output4f.fR - expected4f.fR);
                        float gDiff = fabsf(output4f.fG - expected4f.fG);
                        float bDiff = fabsf(output4f.fB - expected4f.fB);
                        float aDiff = fabsf(output4f.fA - expected4f.fA);
                        static constexpr float kTol = 4 / 255.f;
                        if (rDiff > kTol || gDiff > kTol || bDiff > kTol || aDiff > kTol) {
                            if (constMessage.isEmpty()) {
                                passing = false;

                                constMessage.printf("Processor %s claimed output for const input "
                                        "doesn't match actual output. Error: %f, Tolerance: %f, "
                                        "input: (%f, %f, %f, %f), actual: (%f, %f, %f, %f), "
                                        "expected(%f, %f, %f, %f)", fp->name(),
                                        std::max(rDiff, std::max(gDiff, std::max(bDiff, aDiff))), kTol,
                                        input4f.fR, input4f.fG, input4f.fB, input4f.fA,
                                        output4f.fR, output4f.fG, output4f.fB, output4f.fA,
                                        expected4f.fR, expected4f.fG, expected4f.fB, expected4f.fA);
                            }
                        }
                    }
                    if (input4f.isOpaque() && fp->preservesOpaqueInput() && !output4f.isOpaque()) {
                        passing = false;

                        if (opaqueMessage.isEmpty()) {
                            opaqueMessage.printf("Processor %s claimed opaqueness is preserved but "
                                    "it is not. Input: 0x%08x, Output: 0x%08x.",
                                    fp->name(), input, output);
                        }
                    }

                    if (!passing) {
                        // Regardless of how many optimizations the pixel violates, count it as a
                        // single bad pixel.
                        failedPixelCount++;
                    }
                }
            }

            // Finished analyzing the entire image, see if the number of pixel failures meets the
            // threshold for an FP violating the optimization requirements.
            if (failedPixelCount > kMaxAcceptableFailedPixels) {
                ERRORF(reporter, "Processor violated %d of %d pixels, seed: 0x%08x, processor: %s"
                       ", first failing pixel details are below:",
                       failedPixelCount, kRenderSize * kRenderSize, fpGenerator.initialSeed(),
                       fp->dumpInfo().c_str());

                // Print first failing pixel's details.
                if (!coverageMessage.isEmpty()) {
                    ERRORF(reporter, coverageMessage.c_str());
                }
                if (!constMessage.isEmpty()) {
                    ERRORF(reporter, constMessage.c_str());
                }
                if (!opaqueMessage.isEmpty()) {
                    ERRORF(reporter, opaqueMessage.c_str());
                }

                if (!loggedFirstFailure) {
                    // Print with ERRORF to make sure the encoded image is output
                    SkString input;
                    log_texture_view(context, inputTexture1, &input);
                    SkString output;
                    log_pixels(readData1.data(), kRenderSize, &output);
                    ERRORF(reporter, "Input image: %s\n\n"
                           "===========================================================\n\n"
                           "Output image: %s\n", input.c_str(), output.c_str());
                    loggedFirstFailure = true;
                }
            } else if (failedPixelCount > 0) {
                // Don't trigger an error, but don't just hide the failures either.
                INFOF(reporter, "Processor violated %d of %d pixels (below error threshold), seed: "
                      "0x%08x, processor: %s", failedPixelCount, kRenderSize * kRenderSize,
                      fpGenerator.initialSeed(), fp->dumpInfo().c_str());
                if (!coverageMessage.isEmpty()) {
                    INFOF(reporter, coverageMessage.c_str());
                }
                if (!constMessage.isEmpty()) {
                    INFOF(reporter, constMessage.c_str());
                }
                if (!opaqueMessage.isEmpty()) {
                    INFOF(reporter, opaqueMessage.c_str());
                }
                if (!loggedFirstWarning) {
                    SkString input;
                    log_texture_view(context, inputTexture1, &input);
                    SkString output;
                    log_pixels(readData1.data(), kRenderSize, &output);
                    INFOF(reporter, "Input image: %s\n\n"
                          "===========================================================\n\n"
                          "Output image: %s\n", input.c_str(), output.c_str());
                    loggedFirstWarning = true;
                }
            }
        }
    }
}

static void describe_fp_children(const GrFragmentProcessor& fp,
                                 std::string indent,
                                 SkString* text) {
    for (int index = 0; index < fp.numChildProcessors(); ++index) {
        const GrFragmentProcessor* childFP = fp.childProcessor(index);
        text->appendf("\n%s(#%d) -> %s", indent.c_str(), index, childFP ? childFP->name() : "null");
        if (childFP) {
            describe_fp_children(*childFP, indent + "\t", text);
        }
    }
}

static SkString describe_fp(const GrFragmentProcessor& fp) {
    SkString text;
    text.printf("\n%s", fp.name());
    describe_fp_children(fp, "\t", &text);
    return text;
}

static void assert_processor_equality(skiatest::Reporter* reporter,
                                      const GrFragmentProcessor& fp,
                                      const GrFragmentProcessor& clone) {
    REPORTER_ASSERT(reporter, !strcmp(fp.name(), clone.name()),
                              "%s\n", describe_fp(fp).c_str());
    REPORTER_ASSERT(reporter, fp.compatibleWithCoverageAsAlpha() ==
                              clone.compatibleWithCoverageAsAlpha(),
                              "%s\n", describe_fp(fp).c_str());
    REPORTER_ASSERT(reporter, fp.isEqual(clone),
                              "%s\n", describe_fp(fp).c_str());
    REPORTER_ASSERT(reporter, fp.preservesOpaqueInput() == clone.preservesOpaqueInput(),
                              "%s\n", describe_fp(fp).c_str());
    REPORTER_ASSERT(reporter, fp.hasConstantOutputForConstantInput() ==
                              clone.hasConstantOutputForConstantInput(),
                              "%s\n", describe_fp(fp).c_str());
    REPORTER_ASSERT(reporter, fp.numChildProcessors() == clone.numChildProcessors(),
                              "%s\n", describe_fp(fp).c_str());
    REPORTER_ASSERT(reporter, fp.usesVaryingCoords() == clone.usesVaryingCoords(),
                              "%s\n", describe_fp(fp).c_str());
    REPORTER_ASSERT(reporter, fp.referencesSampleCoords() == clone.referencesSampleCoords(),
                              "%s\n", describe_fp(fp).c_str());
}

static bool verify_identical_render(skiatest::Reporter* reporter, int renderSize,
                                    const char* processorType,
                                    const GrColor readData1[], const GrColor readData2[]) {
    // The ProcessorClone test has a history of being flaky on a number of devices. If an FP clone
    // is logically wrong, it's reasonable to expect it produce a large number of pixel differences
    // in the image. Sporadic pixel violations are more indicative device errors and represents a
    // separate problem.
#if defined(SK_BUILD_FOR_SKQP)
    const int maxAcceptableFailedPixels = 0;  // Strict when running as SKQP
#else
    const int maxAcceptableFailedPixels = 2 * renderSize;  // ~0.002% of the pixels (size 1024*1024)
#endif

    int failedPixelCount = 0;
    int firstWrongX = 0;
    int firstWrongY = 0;
    int idx = 0;
    for (int y = 0; y < renderSize; ++y) {
        for (int x = 0; x < renderSize; ++x, ++idx) {
            if (readData1[idx] != readData2[idx]) {
                if (!failedPixelCount) {
                    firstWrongX = x;
                    firstWrongY = y;
                }
                ++failedPixelCount;
            }
            if (failedPixelCount > maxAcceptableFailedPixels) {
                idx = firstWrongY * renderSize + firstWrongX;
                ERRORF(reporter,
                       "%s produced different output at (%d, %d). "
                       "Input color: 0x%08x, Original Output Color: 0x%08x, "
                       "Clone Output Color: 0x%08x.",
                       processorType, firstWrongX, firstWrongY, input_texel_color(x, y, 0.0f),
                       readData1[idx], readData2[idx]);

                return false;
            }
        }
    }

    return true;
}

static void log_clone_failure(skiatest::Reporter* reporter, int renderSize,
                              GrDirectContext* context, const GrSurfaceProxyView& inputTexture,
                              GrColor pixelsFP[], GrColor pixelsClone[], GrColor pixelsRegen[]) {
    // Write the images out as data URLs for inspection.
    SkString inputURL, origURL, cloneURL, regenURL;
    if (log_texture_view(context, inputTexture, &inputURL) &&
        log_pixels(pixelsFP, renderSize, &origURL) &&
        log_pixels(pixelsClone, renderSize, &cloneURL) &&
        log_pixels(pixelsRegen, renderSize, &regenURL)) {
        ERRORF(reporter,
               "\nInput image:\n%s\n\n"
               "==========================================================="
               "\n\n"
               "Orig output image:\n%s\n"
               "==========================================================="
               "\n\n"
               "Clone output image:\n%s\n"
               "==========================================================="
               "\n\n"
               "Regen output image:\n%s\n",
               inputURL.c_str(), origURL.c_str(), cloneURL.c_str(), regenURL.c_str());
    }
}

// Tests that a fragment processor returned by GrFragmentProcessor::clone() is equivalent to its
// progenitor.
DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ProcessorCloneTest, reporter, ctxInfo) {
    GrDirectContext* context = ctxInfo.directContext();
    GrResourceProvider* resourceProvider = context->priv().resourceProvider();

    TestFPGenerator fpGenerator{context, resourceProvider};
    if (!fpGenerator.init()) {
        ERRORF(reporter, "Could not initialize TestFPGenerator");
        return;
    }

    // Make the destination context for the test.
    static constexpr int kRenderSize = 1024;
    auto rtc = GrRenderTargetContext::Make(
            context, GrColorType::kRGBA_8888, nullptr, SkBackingFit::kExact,
            {kRenderSize, kRenderSize});

    GrSurfaceProxyView inputTexture = make_input_texture(context, kRenderSize, kRenderSize, 0.0f);

    // On failure we write out images, but just write the first failing set as the print is very
    // large.
    bool loggedFirstFailure = false;

    // Storage for the original frame's readback and the readback of its clone.
    std::vector<GrColor> readDataFP(kRenderSize * kRenderSize);
    std::vector<GrColor> readDataClone(kRenderSize * kRenderSize);
    std::vector<GrColor> readDataRegen(kRenderSize * kRenderSize);

    // Because processor factories configure themselves in random ways, this is not exhaustive.
    for (int i = 0; i < GrFragmentProcessorTestFactory::Count(); ++i) {
        static constexpr int kTimesToInvokeFactory = 10;
        for (int j = 0; j < kTimesToInvokeFactory; ++j) {
            fpGenerator.reroll();
            std::unique_ptr<GrFragmentProcessor> fp =
                    fpGenerator.make(i, /*randomTreeDepth=*/1, /*inputFP=*/nullptr);
            std::unique_ptr<GrFragmentProcessor> regen =
                    fpGenerator.make(i, /*randomTreeDepth=*/1, /*inputFP=*/nullptr);
            std::unique_ptr<GrFragmentProcessor> clone = fp->clone();
            if (!clone) {
                ERRORF(reporter, "Clone of processor %s failed.", fp->name());
                continue;
            }
            assert_processor_equality(reporter, *fp, *clone);

            // Draw with original and read back the results.
            render_fp(context, rtc.get(), std::move(fp), readDataFP.data());

            // Draw with clone and read back the results.
            render_fp(context, rtc.get(), std::move(clone), readDataClone.data());

            // Check that the results are the same.
            if (!verify_identical_render(reporter, kRenderSize, "Processor clone",
                                         readDataFP.data(), readDataClone.data())) {
                // Dump a description from the regenerated processor (since the original FP has
                // already been consumed).
                ERRORF(reporter, "FP hierarchy:\n%s\n", describe_fp(*regen).c_str());

                // Render and readback output from the regenerated FP. If this also mismatches, the
                // FP itself doesn't generate consistent output. This could happen if:
                // - the FP's TestCreate() does not always generate the same FP from a given seed
                // - the FP's Make() does not always generate the same FP when given the same inputs
                // - the FP itself generates inconsistent pixels (shader UB?)
                // - the driver has a bug
                render_fp(context, rtc.get(), std::move(regen), readDataRegen.data());

                if (!verify_identical_render(reporter, kRenderSize, "Regenerated processor",
                                             readDataFP.data(), readDataRegen.data())) {
                    ERRORF(reporter, "Output from regen did not match original!\n");
                } else {
                    ERRORF(reporter, "Regenerated processor output matches original results.\n");
                }

                // If this is the first time we've encountered a cloning failure, log the generated
                // images to the reporter as data URLs.
                if (!loggedFirstFailure) {
                    log_clone_failure(reporter, kRenderSize, context, inputTexture,
                                      readDataFP.data(), readDataClone.data(),
                                      readDataRegen.data());
                    loggedFirstFailure = true;
                }
            }
        }
    }
}

#endif  // GR_TEST_UTILS
