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

#include "SkTypes.h"
#include "Test.h"

#include "GrClip.h"
#include "GrContextPriv.h"
#include "GrDrawingManager.h"
#include "GrPaint.h"
#include "GrPathRenderer.h"
#include "GrRecordingContext.h"
#include "GrRecordingContextPriv.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
#include "GrShape.h"
#include "GrTexture.h"
#include "SkExchange.h"
#include "SkMatrix.h"
#include "SkPathPriv.h"
#include "SkRect.h"
#include "ToolUtils.h"
#include "ccpr/GrCCPathCache.h"
#include "ccpr/GrCoverageCountingPathRenderer.h"
#include "mock/GrMockTypes.h"

#include <cmath>

static constexpr int kCanvasSize = 100;

class CCPRClip : public GrClip {
public:
    CCPRClip(GrCoverageCountingPathRenderer* ccpr, const SkPath& path) : fCCPR(ccpr), fPath(path) {}

private:
    bool apply(GrRecordingContext* context, GrRenderTargetContext* rtc, bool useHWAA,
               bool hasUserStencilSettings, GrAppliedClip* out, SkRect* bounds) const override {
        out->addCoverageFP(fCCPR->makeClipProcessor(rtc->priv().testingOnly_getOpListID(), fPath,
                                                    SkIRect::MakeWH(rtc->width(), rtc->height()),
                                                    rtc->width(), rtc->height(),
                                                    *context->priv().caps()));
        return true;
    }
    bool quickContains(const SkRect&) const final { return false; }
    bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; }
    void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final {
        rect->set(0, 0, width, height);
        if (iior) {
            *iior = false;
        }
    }
    GrCoverageCountingPathRenderer* const fCCPR;
    const SkPath fPath;
};

class CCPRPathDrawer {
public:
    CCPRPathDrawer(sk_sp<GrContext> ctx, skiatest::Reporter* reporter, bool doStroke)
            : fCtx(ctx)
            , fCCPR(fCtx->priv().drawingManager()->getCoverageCountingPathRenderer())
            , fRTC(fCtx->priv().makeDeferredRenderTargetContext(
                ctx->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType),
                SkBackingFit::kExact, kCanvasSize, kCanvasSize, kRGBA_8888_GrPixelConfig,
                nullptr))
            , fDoStroke(doStroke) {
        if (!fCCPR) {
            ERRORF(reporter, "ccpr not enabled in GrContext for ccpr tests");
        }
        if (!fRTC) {
            ERRORF(reporter, "failed to create GrRenderTargetContext for ccpr tests");
        }
    }

    GrContext* ctx() const { return fCtx.get(); }
    GrCoverageCountingPathRenderer* ccpr() const { return fCCPR; }

    bool valid() const { return fCCPR && fRTC; }
    void clear() const { fRTC->clear(nullptr, SK_PMColor4fTRANSPARENT,
                                     GrRenderTargetContext::CanClearFullscreen::kYes); }
    void destroyGrContext() {
        SkASSERT(fRTC->unique());
        SkASSERT(fCtx->unique());
        fRTC.reset();
        fCCPR = nullptr;
        fCtx.reset();
    }

    void drawPath(const SkPath& path, const SkMatrix& matrix = SkMatrix::I()) const {
        SkASSERT(this->valid());

        GrPaint paint;
        paint.setColor4f({ 0, 1, 0, 1 });

        GrNoClip noClip;
        SkIRect clipBounds = SkIRect::MakeWH(kCanvasSize, kCanvasSize);

        GrShape shape;
        if (!fDoStroke) {
            shape = GrShape(path);
        } else {
            // Use hairlines for now, since they are the only stroke type that doesn't require a
            // rigid-body transform. The CCPR stroke code makes no distinction between hairlines
            // and regular strokes other than how it decides the device-space stroke width.
            SkStrokeRec stroke(SkStrokeRec::kHairline_InitStyle);
            stroke.setStrokeParams(SkPaint::kRound_Cap, SkPaint::kMiter_Join, 4);
            shape = GrShape(path, GrStyle(stroke, nullptr));
        }

        fCCPR->testingOnly_drawPathDirectly({
                fCtx.get(), std::move(paint), &GrUserStencilSettings::kUnused, fRTC.get(), &noClip,
                &clipBounds, &matrix, &shape, GrPathRenderer::AATypeFlags::kCoverage, false});
    }

    void clipFullscreenRect(SkPath clipPath, SkPMColor4f color = { 0, 1, 0, 1 }) {
        SkASSERT(this->valid());

        GrPaint paint;
        paint.setColor4f(color);

        fRTC->drawRect(CCPRClip(fCCPR, clipPath), std::move(paint), GrAA::kYes, SkMatrix::I(),
                       SkRect::MakeIWH(kCanvasSize, kCanvasSize));
    }

    void flush() const {
        SkASSERT(this->valid());
        fCtx->flush();
    }

private:
    sk_sp<GrContext> fCtx;
    GrCoverageCountingPathRenderer* fCCPR;
    sk_sp<GrRenderTargetContext> fRTC;
    const bool fDoStroke;
};

class CCPRTest {
public:
    void run(skiatest::Reporter* reporter, bool doStroke) {
        GrMockOptions mockOptions;
        mockOptions.fInstanceAttribSupport = true;
        mockOptions.fHalfFloatVertexAttributeSupport = true;
        mockOptions.fMapBufferFlags = GrCaps::kCanMap_MapFlag;
        mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderability =
                GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
        mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fTexturable = true;
        mockOptions.fConfigOptions[kAlpha_8_GrPixelConfig].fRenderability =
                GrMockOptions::ConfigOptions::Renderability::kNonMSAA;
        mockOptions.fConfigOptions[kAlpha_8_GrPixelConfig].fTexturable = true;
        mockOptions.fGeometryShaderSupport = true;
        mockOptions.fIntegerSupport = true;
        mockOptions.fFlatInterpolationSupport = true;

        GrContextOptions ctxOptions;
        ctxOptions.fDisableCoverageCountingPaths = false;
        ctxOptions.fAllowPathMaskCaching = false;
        ctxOptions.fGpuPathRenderers = GpuPathRenderers::kCoverageCounting;

        this->customizeOptions(&mockOptions, &ctxOptions);

        sk_sp<GrContext> mockContext = GrContext::MakeMock(&mockOptions, ctxOptions);
        if (!mockContext) {
            ERRORF(reporter, "could not create mock context");
            return;
        }
        if (!mockContext->unique()) {
            ERRORF(reporter, "mock context is not unique");
            return;
        }

        CCPRPathDrawer ccpr(skstd::exchange(mockContext, nullptr), reporter, doStroke);
        if (!ccpr.valid()) {
            return;
        }

        fPath.moveTo(0, 0);
        fPath.cubicTo(50, 50, 0, 50, 50, 0);
        this->onRun(reporter, ccpr);
    }

    virtual ~CCPRTest() {}

protected:
    virtual void customizeOptions(GrMockOptions*, GrContextOptions*) {}
    virtual void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) = 0;

    SkPath fPath;
};

#define DEF_CCPR_TEST(name) \
    DEF_GPUTEST(name, reporter, /* options */) { \
        name test; \
        test.run(reporter, false); \
        test.run(reporter, true); \
    }

class CCPR_cleanup : public CCPRTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override {
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));

        // Ensure paths get unreffed.
        for (int i = 0; i < 10; ++i) {
            ccpr.drawPath(fPath);
        }
        REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
        ccpr.flush();
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));

        // Ensure clip paths get unreffed.
        for (int i = 0; i < 10; ++i) {
            ccpr.clipFullscreenRect(fPath);
        }
        REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
        ccpr.flush();
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));

        // Ensure paths get unreffed when we delete the context without flushing.
        for (int i = 0; i < 10; ++i) {
            ccpr.drawPath(fPath);
            ccpr.clipFullscreenRect(fPath);
        }
        REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));

        ccpr.destroyGrContext();
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
    }
};
DEF_CCPR_TEST(CCPR_cleanup)

class CCPR_cleanupWithTexAllocFail : public CCPR_cleanup {
    void customizeOptions(GrMockOptions* mockOptions, GrContextOptions*) override {
        mockOptions->fFailTextureAllocations = true;
    }
};
DEF_CCPR_TEST(CCPR_cleanupWithTexAllocFail)

class CCPR_unregisterCulledOps : public CCPRTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override {
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));

        // Ensure Ops get unregistered from CCPR when culled early.
        ccpr.drawPath(fPath);
        REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
        ccpr.clear(); // Clear should delete the CCPR Op.
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
        ccpr.flush(); // Should not crash (DrawPathsOp should have unregistered itself).

        // Ensure Op unregisters work when we delete the context without flushing.
        ccpr.drawPath(fPath);
        REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
        ccpr.clear(); // Clear should delete the CCPR DrawPathsOp.
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
        ccpr.destroyGrContext(); // Should not crash (DrawPathsOp should have unregistered itself).
    }
};
DEF_CCPR_TEST(CCPR_unregisterCulledOps)

class CCPR_parseEmptyPath : public CCPRTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override {
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));

        // Make a path large enough that ccpr chooses to crop it by the RT bounds, and ends up with
        // an empty path.
        SkPath largeOutsidePath;
        largeOutsidePath.moveTo(-1e30f, -1e30f);
        largeOutsidePath.lineTo(-1e30f, +1e30f);
        largeOutsidePath.lineTo(-1e10f, +1e30f);
        ccpr.drawPath(largeOutsidePath);

        // Normally an empty path is culled before reaching ccpr, however we use a back door for
        // testing so this path will make it.
        SkPath emptyPath;
        SkASSERT(emptyPath.isEmpty());
        ccpr.drawPath(emptyPath);

        // This is the test. It will exercise various internal asserts and verify we do not crash.
        ccpr.flush();

        // Now try again with clips.
        ccpr.clipFullscreenRect(largeOutsidePath);
        ccpr.clipFullscreenRect(emptyPath);
        ccpr.flush();

        // ... and both.
        ccpr.drawPath(largeOutsidePath);
        ccpr.clipFullscreenRect(largeOutsidePath);
        ccpr.drawPath(emptyPath);
        ccpr.clipFullscreenRect(emptyPath);
        ccpr.flush();
    }
};
DEF_CCPR_TEST(CCPR_parseEmptyPath)

static int get_mock_texture_id(const GrTexture* texture) {
    const GrBackendTexture& backingTexture = texture->getBackendTexture();
    SkASSERT(GrBackendApi::kMock == backingTexture.backend());

    if (!backingTexture.isValid()) {
        return 0;
    }

    GrMockTextureInfo info;
    backingTexture.getMockTextureInfo(&info);
    return info.fID;
}

// Base class for cache path unit tests.
class CCPRCacheTest : public CCPRTest {
protected:
    // Registers as an onFlush callback in order to snag the CCPR per-flush resources and note the
    // texture IDs.
    class RecordLastMockAtlasIDs : public GrOnFlushCallbackObject {
    public:
        RecordLastMockAtlasIDs(sk_sp<GrCoverageCountingPathRenderer> ccpr) : fCCPR(ccpr) {}

        int lastCopyAtlasID() const { return fLastCopyAtlasID; }
        int lastRenderedAtlasID() const { return fLastRenderedAtlasID; }

        void preFlush(GrOnFlushResourceProvider*, const uint32_t* opListIDs, int numOpListIDs,
                      SkTArray<sk_sp<GrRenderTargetContext>>* out) override {
            fLastRenderedAtlasID = fLastCopyAtlasID = 0;

            const GrCCPerFlushResources* resources = fCCPR->testingOnly_getCurrentFlushResources();
            if (!resources) {
                return;
            }

            if (const GrTexture* tex = resources->testingOnly_frontCopyAtlasTexture()) {
                fLastCopyAtlasID = get_mock_texture_id(tex);
            }
            if (const GrTexture* tex = resources->testingOnly_frontRenderedAtlasTexture()) {
                fLastRenderedAtlasID = get_mock_texture_id(tex);
            }
        }

        void postFlush(GrDeferredUploadToken, const uint32_t*, int) override {}

    private:
        sk_sp<GrCoverageCountingPathRenderer> fCCPR;
        int fLastCopyAtlasID = 0;
        int fLastRenderedAtlasID = 0;
    };

    CCPRCacheTest() {
        static constexpr int primes[11] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};

        SkRandom rand;
        for (size_t i = 0; i < SK_ARRAY_COUNT(fPaths); ++i) {
            int numPts = rand.nextRangeU(GrShape::kMaxKeyFromDataVerbCnt + 1,
                                         GrShape::kMaxKeyFromDataVerbCnt * 2);
            int step;
            do {
                step = primes[rand.nextU() % SK_ARRAY_COUNT(primes)];
            } while (step == numPts);
            fPaths[i] = ToolUtils::make_star(SkRect::MakeLTRB(0, 0, 1, 1), numPts, step);
        }
    }

    void drawPathsAndFlush(CCPRPathDrawer& ccpr, const SkMatrix& m) {
        this->drawPathsAndFlush(ccpr, &m, 1);
    }
    void drawPathsAndFlush(CCPRPathDrawer& ccpr, const SkMatrix* matrices, int numMatrices) {
        // Draw all the paths.
        for (size_t i = 0; i < SK_ARRAY_COUNT(fPaths); ++i) {
            ccpr.drawPath(fPaths[i], matrices[i % numMatrices]);
        }
        // Re-draw a few paths, to test the case where a cache entry is hit more than once in a
        // single flush.
        SkRandom rand;
        int duplicateIndices[10];
        for (size_t i = 0; i < SK_ARRAY_COUNT(duplicateIndices); ++i) {
            duplicateIndices[i] = rand.nextULessThan(SK_ARRAY_COUNT(fPaths));
        }
        for (size_t i = 0; i < SK_ARRAY_COUNT(duplicateIndices); ++i) {
            for (size_t j = 0; j <= i; ++j) {
                int idx = duplicateIndices[j];
                ccpr.drawPath(fPaths[idx], matrices[idx % numMatrices]);
            }
        }
        ccpr.flush();
    }

private:
    void customizeOptions(GrMockOptions*, GrContextOptions* ctxOptions) override {
        ctxOptions->fAllowPathMaskCaching = true;
    }

    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) final {
        RecordLastMockAtlasIDs atlasIDRecorder(sk_ref_sp(ccpr.ccpr()));
        ccpr.ctx()->priv().addOnFlushCallbackObject(&atlasIDRecorder);

        this->onRun(reporter, ccpr, atlasIDRecorder);

        ccpr.ctx()->priv().testingOnly_flushAndRemoveOnFlushCallbackObject(&atlasIDRecorder);
    }

    virtual void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
                       const RecordLastMockAtlasIDs&) = 0;

protected:
    SkPath fPaths[350];
};

// Ensures ccpr always reuses the same atlas texture in the animation use case.
class CCPR_cache_animationAtlasReuse : public CCPRCacheTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
               const RecordLastMockAtlasIDs& atlasIDRecorder) override {
        SkMatrix m = SkMatrix::MakeTrans(kCanvasSize/2, kCanvasSize/2);
        m.preScale(80, 80);
        m.preTranslate(-.5,-.5);
        this->drawPathsAndFlush(ccpr, m);

        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
        REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
        const int atlasID = atlasIDRecorder.lastRenderedAtlasID();

        // Ensures we always reuse the same atlas texture in the animation use case.
        for (int i = 0; i < 12; ++i) {
            // 59 is prime, so we will hit every integer modulo 360 before repeating.
            m.preRotate(59, .5, .5);

            // Go twice. Paths have to get drawn twice with the same matrix before we cache their
            // atlas. This makes sure that on the subsequent draw, after an atlas has been cached
            // and is then invalidated since the matrix will change, that the same underlying
            // texture object is still reused for the next atlas.
            for (int j = 0; j < 2; ++j) {
                this->drawPathsAndFlush(ccpr, m);
                // Nothing should be copied to an 8-bit atlas after just two draws.
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                REPORTER_ASSERT(reporter, atlasIDRecorder.lastRenderedAtlasID() == atlasID);
            }
        }

        // Do the last draw again. (On draw 3 they should get copied to an 8-bit atlas.)
        this->drawPathsAndFlush(ccpr, m);
        REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastCopyAtlasID());
        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());

        // Now double-check that everything continues to hit the cache as expected when the matrix
        // doesn't change.
        for (int i = 0; i < 10; ++i) {
            this->drawPathsAndFlush(ccpr, m);
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());
        }
    }
};
DEF_CCPR_TEST(CCPR_cache_animationAtlasReuse)

class CCPR_cache_recycleEntries : public CCPRCacheTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
               const RecordLastMockAtlasIDs& atlasIDRecorder) override {
        SkMatrix m = SkMatrix::MakeTrans(kCanvasSize/2, kCanvasSize/2);
        m.preScale(80, 80);
        m.preTranslate(-.5,-.5);

        auto cache = ccpr.ccpr()->testingOnly_getPathCache();
        REPORTER_ASSERT(reporter, cache);

        const auto& lru = cache->testingOnly_getLRU();

        SkTArray<const void*> expectedPtrs;

        // Ensures we always reuse the same atlas texture in the animation use case.
        for (int i = 0; i < 5; ++i) {
            // 59 is prime, so we will hit every integer modulo 360 before repeating.
            m.preRotate(59, .5, .5);

            // Go twice. Paths have to get drawn twice with the same matrix before we cache their
            // atlas.
            for (int j = 0; j < 2; ++j) {
                this->drawPathsAndFlush(ccpr, m);
                // Nothing should be copied to an 8-bit atlas after just two draws.
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
            }

            int idx = 0;
            for (const GrCCPathCacheEntry* entry : lru) {
                if (0 == i) {
                    expectedPtrs.push_back(entry);
                } else {
                    // The same pointer should have been recycled for the new matrix.
                    REPORTER_ASSERT(reporter, entry == expectedPtrs[idx]);
                }
                ++idx;
            }
        }
    }
};
DEF_CCPR_TEST(CCPR_cache_recycleEntries)

// Ensures mostly-visible paths get their full mask cached.
class CCPR_cache_mostlyVisible : public CCPRCacheTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
               const RecordLastMockAtlasIDs& atlasIDRecorder) override {
        SkMatrix matrices[3] = {
            SkMatrix::MakeScale(kCanvasSize/2, kCanvasSize/2), // Fully visible.
            SkMatrix::MakeScale(kCanvasSize * 1.25, kCanvasSize * 1.25), // Mostly visible.
            SkMatrix::MakeScale(kCanvasSize * 1.5, kCanvasSize * 1.5), // Mostly NOT visible.
        };

        for (int i = 0; i < 10; ++i) {
            this->drawPathsAndFlush(ccpr, matrices, 3);
            if (2 == i) {
                // The mostly-visible paths should still get cached.
                REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastCopyAtlasID());
            } else {
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
            }
            // Ensure mostly NOT-visible paths never get cached.
            REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
        }

        // Clear the path cache.
        this->drawPathsAndFlush(ccpr, SkMatrix::I());

        // Now only draw the fully/mostly visible ones.
        for (int i = 0; i < 2; ++i) {
            this->drawPathsAndFlush(ccpr, matrices, 2);
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
            REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
        }

        // On draw 3 they should get copied to an 8-bit atlas.
        this->drawPathsAndFlush(ccpr, matrices, 2);
        REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastCopyAtlasID());
        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());

        for (int i = 0; i < 10; ++i) {
            this->drawPathsAndFlush(ccpr, matrices, 2);
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());
        }

        // Draw a different part of the path to ensure the full mask was cached.
        matrices[1].postTranslate(SkScalarFloorToInt(kCanvasSize * -.25f),
                                  SkScalarFloorToInt(kCanvasSize * -.25f));
        for (int i = 0; i < 10; ++i) {
            this->drawPathsAndFlush(ccpr, matrices, 2);
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());
        }
    }
};
DEF_CCPR_TEST(CCPR_cache_mostlyVisible)

// Ensures GrContext::performDeferredCleanup works.
class CCPR_cache_deferredCleanup : public CCPRCacheTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
               const RecordLastMockAtlasIDs& atlasIDRecorder) override {
        SkMatrix m = SkMatrix::MakeScale(20, 20);
        int lastRenderedAtlasID = 0;

        for (int i = 0; i < 5; ++i) {
            this->drawPathsAndFlush(ccpr, m);
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
            REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
            int renderedAtlasID = atlasIDRecorder.lastRenderedAtlasID();
            REPORTER_ASSERT(reporter, renderedAtlasID != lastRenderedAtlasID);
            lastRenderedAtlasID = renderedAtlasID;

            this->drawPathsAndFlush(ccpr, m);
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
            REPORTER_ASSERT(reporter, lastRenderedAtlasID == atlasIDRecorder.lastRenderedAtlasID());

            // On draw 3 they should get copied to an 8-bit atlas.
            this->drawPathsAndFlush(ccpr, m);
            REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastCopyAtlasID());
            REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());

            for (int i = 0; i < 10; ++i) {
                this->drawPathsAndFlush(ccpr, m);
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());
            }

            ccpr.ctx()->performDeferredCleanup(std::chrono::milliseconds(0));
        }
    }
};
DEF_CCPR_TEST(CCPR_cache_deferredCleanup)

// Verifies the cache/hash table internals.
class CCPR_cache_hashTable : public CCPRCacheTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
               const RecordLastMockAtlasIDs& atlasIDRecorder) override {
        using CoverageType = GrCCAtlas::CoverageType;
        SkMatrix m = SkMatrix::MakeScale(20, 20);

        for (int i = 0; i < 5; ++i) {
            this->drawPathsAndFlush(ccpr, m);
            if (2 == i) {
                REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastCopyAtlasID());
            } else {
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
            }
            if (i < 2) {
                REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
            } else {
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());
            }

            auto cache = ccpr.ccpr()->testingOnly_getPathCache();
            REPORTER_ASSERT(reporter, cache);

            const auto& hash = cache->testingOnly_getHashTable();
            const auto& lru = cache->testingOnly_getLRU();
            int count = 0;
            for (GrCCPathCacheEntry* entry : lru) {
                auto* node = hash.find(entry->cacheKey());
                REPORTER_ASSERT(reporter, node);
                REPORTER_ASSERT(reporter, node->entry() == entry);
                REPORTER_ASSERT(reporter, 0 == entry->testingOnly_peekOnFlushRefCnt());
                REPORTER_ASSERT(reporter, entry->unique());
                if (0 == i) {
                    REPORTER_ASSERT(reporter, !entry->cachedAtlas());
                } else {
                    const GrCCCachedAtlas* cachedAtlas = entry->cachedAtlas();
                    REPORTER_ASSERT(reporter, cachedAtlas);
                    if (1 == i) {
                        REPORTER_ASSERT(reporter, CoverageType::kFP16_CoverageCount
                                                          == cachedAtlas->coverageType());
                    } else {
                        REPORTER_ASSERT(reporter, CoverageType::kA8_LiteralCoverage
                                                          == cachedAtlas->coverageType());
                    }
                    REPORTER_ASSERT(reporter, cachedAtlas->textureKey().isValid());
                    // The actual proxy should not be held past the end of a flush.
                    REPORTER_ASSERT(reporter, !cachedAtlas->getOnFlushProxy());
                    REPORTER_ASSERT(reporter, 0 == cachedAtlas->testingOnly_peekOnFlushRefCnt());
                }
                ++count;
            }
            REPORTER_ASSERT(reporter, hash.count() == count);
        }
    }
};
DEF_CCPR_TEST(CCPR_cache_hashTable)

// Ensures paths get cached even when using a sporadic flushing pattern and drawing out of order
// (a la Chrome tiles).
class CCPR_cache_multiFlush : public CCPRCacheTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
               const RecordLastMockAtlasIDs& atlasIDRecorder) override {
        static constexpr int kNumPaths = SK_ARRAY_COUNT(fPaths);
        static constexpr int kBigPrimes[] = {
                9323, 11059, 22993, 38749, 45127, 53147, 64853, 77969, 83269, 99989};

        SkRandom rand;
        SkMatrix m = SkMatrix::I();

        for (size_t i = 0; i < SK_ARRAY_COUNT(kBigPrimes); ++i) {
            int prime = kBigPrimes[i];
            int endPathIdx = (int)rand.nextULessThan(kNumPaths);
            int pathIdx = endPathIdx;
            int nextFlush = rand.nextRangeU(1, 47);
            for (int j = 0; j < kNumPaths; ++j) {
                pathIdx = (pathIdx + prime) % kNumPaths;
                int repeat = rand.nextRangeU(1, 3);
                for (int k = 0; k < repeat; ++k) {
                    ccpr.drawPath(fPaths[pathIdx], m);
                }
                if (nextFlush == j) {
                    ccpr.flush();
                    // The paths are small enough that we should never copy to an A8 atlas.
                    REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                    if (i < 2) {
                        REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
                    } else {
                        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());
                    }
                    nextFlush = SkTMin(j + (int)rand.nextRangeU(1, 29), kNumPaths - 1);
                }
            }
            SkASSERT(endPathIdx == pathIdx % kNumPaths);
        }
    }
};
DEF_CCPR_TEST(CCPR_cache_multiFlush)

// Ensures a path drawn over mutiple tiles gets cached.
class CCPR_cache_multiTileCache : public CCPRCacheTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
               const RecordLastMockAtlasIDs& atlasIDRecorder) override {
        // Make sure a path drawn over 9 tiles gets cached (1 tile out of 9 is >10% visibility).
        const SkMatrix m0 = SkMatrix::MakeScale(kCanvasSize*3, kCanvasSize*3);
        const SkPath p0 = fPaths[0];
        for (int i = 0; i < 9; ++i) {
            static constexpr int kRowOrder[9] = {0,1,1,0,2,2,2,1,0};
            static constexpr int kColumnOrder[9] = {0,0,1,1,0,1,2,2,2};

            SkMatrix tileM = m0;
            tileM.postTranslate(-kCanvasSize * kColumnOrder[i], -kCanvasSize * kRowOrder[i]);
            ccpr.drawPath(p0, tileM);
            ccpr.flush();
            if (i < 5) {
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
            } else if (5 == i) {
                REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastCopyAtlasID());
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());
            } else {
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());
            }
        }

        // Now make sure paths don't get cached when visibility is <10% for every draw (12 tiles).
        const SkMatrix m1 = SkMatrix::MakeScale(kCanvasSize*4, kCanvasSize*3);
        const SkPath p1 = fPaths[1];
        for (int row = 0; row < 3; ++row) {
            for (int col = 0; col < 4; ++col) {
                SkMatrix tileM = m1;
                tileM.postTranslate(-kCanvasSize * col, -kCanvasSize * row);
                ccpr.drawPath(p1, tileM);
                ccpr.flush();
                REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
            }
        }

        // Double-check the cache is still intact.
        ccpr.drawPath(p0, m0);
        ccpr.flush();
        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());

        ccpr.drawPath(p1, m1);
        ccpr.flush();
        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
        REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastRenderedAtlasID());
    }
};
DEF_CCPR_TEST(CCPR_cache_multiTileCache)

// This test exercises CCPR's cache capabilities by drawing many paths with two different
// transformation matrices. We then vary the matrices independently by whole and partial pixels,
// and verify the caching behaved as expected.
class CCPR_cache_partialInvalidate : public CCPRCacheTest {
    void customizeOptions(GrMockOptions*, GrContextOptions* ctxOptions) override {
        ctxOptions->fAllowPathMaskCaching = true;
    }

    static constexpr int kPathSize = 4;

    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr,
               const RecordLastMockAtlasIDs& atlasIDRecorder) override {
        SkMatrix matrices[2] = {
            SkMatrix::MakeTrans(5, 5),
            SkMatrix::MakeTrans(kCanvasSize - kPathSize - 5, kCanvasSize - kPathSize - 5)
        };
        matrices[0].preScale(kPathSize, kPathSize);
        matrices[1].preScale(kPathSize, kPathSize);

        int firstAtlasID = 0;

        for (int iterIdx = 0; iterIdx < 4*3*2; ++iterIdx) {
            this->drawPathsAndFlush(ccpr, matrices, 2);

            if (0 == iterIdx) {
                // First iteration: just note the ID of the stashed atlas and continue.
                firstAtlasID = atlasIDRecorder.lastRenderedAtlasID();
                REPORTER_ASSERT(reporter, 0 != firstAtlasID);
                continue;
            }

            int testIdx = (iterIdx/2) % 3;
            int repetitionIdx = iterIdx % 2;
            switch (testIdx) {
                case 0:
                    if (0 == repetitionIdx) {
                        // This is the big test. New paths were drawn twice last round. On hit 2
                        // (last time), 'firstAtlasID' was cached as a 16-bit atlas. Now, on hit 3,
                        // these paths should be copied out of 'firstAtlasID', and into an A8 atlas.
                        // THEN: we should recycle 'firstAtlasID' and reuse that same texture to
                        // render the new masks.
                        REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastCopyAtlasID());
                        REPORTER_ASSERT(reporter,
                                        atlasIDRecorder.lastRenderedAtlasID() == firstAtlasID);
                    } else {
                        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                        // This is hit 2 for the new masks. Next time they will be copied to an A8
                        // atlas.
                        REPORTER_ASSERT(reporter,
                                        atlasIDRecorder.lastRenderedAtlasID() == firstAtlasID);
                    }

                    if (1 == repetitionIdx) {
                        // Integer translates: all path masks stay valid.
                        matrices[0].preTranslate(-1, -1);
                        matrices[1].preTranslate(1, 1);
                    }
                    break;

                case 1:
                    if (0 == repetitionIdx) {
                        // New paths were drawn twice last round. The third hit (now) they should be
                        // copied to an A8 atlas.
                        REPORTER_ASSERT(reporter, 0 != atlasIDRecorder.lastCopyAtlasID());
                    } else {
                        REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());
                    }

                    // This draw should have gotten 100% cache hits; we only did integer translates
                    // last time (or none if it was the first flush). Therefore, everything should
                    // have been cached.
                    REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastRenderedAtlasID());

                    if (1 == repetitionIdx) {
                        // Invalidate even path masks.
                        matrices[0].preTranslate(1.6f, 1.4f);
                    }
                    break;

                case 2:
                    // No new masks to copy from last time; it had 100% cache hits.
                    REPORTER_ASSERT(reporter, 0 == atlasIDRecorder.lastCopyAtlasID());

                    // Even path masks were invalidated last iteration by a subpixel translate.
                    // They should have been re-rendered this time in the original 'firstAtlasID'
                    // texture.
                    REPORTER_ASSERT(reporter,
                                    atlasIDRecorder.lastRenderedAtlasID() == firstAtlasID);

                    if (1 == repetitionIdx) {
                        // Invalidate odd path masks.
                        matrices[1].preTranslate(-1.4f, -1.6f);
                    }
                    break;
            }
        }
    }
};
DEF_CCPR_TEST(CCPR_cache_partialInvalidate)

class CCPR_unrefPerOpListPathsBeforeOps : public CCPRTest {
    void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override {
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
        for (int i = 0; i < 10000; ++i) {
            // Draw enough paths to make the arena allocator hit the heap.
            ccpr.drawPath(fPath);
        }

        // Unref the GrCCPerOpListPaths object.
        auto perOpListPathsMap = ccpr.ccpr()->detachPendingPaths();
        perOpListPathsMap.clear();

        // Now delete the Op and all its draws.
        REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath));
        ccpr.flush();
        REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath));
    }
};
DEF_CCPR_TEST(CCPR_unrefPerOpListPathsBeforeOps)

class CCPRRenderingTest {
public:
    void run(skiatest::Reporter* reporter, GrContext* ctx, bool doStroke) const {
        if (!ctx->priv().drawingManager()->getCoverageCountingPathRenderer()) {
            return; // CCPR is not enabled on this GPU.
        }
        CCPRPathDrawer ccpr(sk_ref_sp(ctx), reporter, doStroke);
        if (!ccpr.valid()) {
            return;
        }
        this->onRun(reporter, ccpr);
    }

    virtual ~CCPRRenderingTest() {}

protected:
    virtual void onRun(skiatest::Reporter* reporter, const CCPRPathDrawer& ccpr) const = 0;
};

#define DEF_CCPR_RENDERING_TEST(name) \
    DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, ctxInfo) { \
        name test; \
        test.run(reporter, ctxInfo.grContext(), false); \
        test.run(reporter, ctxInfo.grContext(), true); \
    }

class CCPR_busyPath : public CCPRRenderingTest {
    void onRun(skiatest::Reporter* reporter, const CCPRPathDrawer& ccpr) const override {
        static constexpr int kNumBusyVerbs = 1 << 17;
        ccpr.clear();
        SkPath busyPath;
        busyPath.moveTo(0, 0); // top left
        busyPath.lineTo(kCanvasSize, kCanvasSize); // bottom right
        for (int i = 2; i < kNumBusyVerbs; ++i) {
            float offset = i * ((float)kCanvasSize / kNumBusyVerbs);
            busyPath.lineTo(kCanvasSize - offset, kCanvasSize + offset); // offscreen
        }
        ccpr.drawPath(busyPath);

        ccpr.flush(); // If this doesn't crash, the test passed.
                      // If it does, maybe fiddle with fMaxInstancesPerDrawArraysWithoutCrashing in
                      // your platform's GrGLCaps.
    }
};
DEF_CCPR_RENDERING_TEST(CCPR_busyPath)
