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

#include "include/core/SkBlendMode.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/SkColorData.h"
#include "include/private/base/SkAlign.h"
#include "include/private/base/SkTemplates.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkSLTypeShared.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/ganesh/GrAppliedClip.h"
#include "src/gpu/ganesh/GrBuffer.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrDrawingManager.h"
#include "src/gpu/ganesh/GrGeometryProcessor.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/GrGpuBuffer.h"
#include "src/gpu/ganesh/GrImageInfo.h"
#include "src/gpu/ganesh/GrMeshDrawTarget.h"
#include "src/gpu/ganesh/GrOpFlushState.h"
#include "src/gpu/ganesh/GrPipeline.h"
#include "src/gpu/ganesh/GrPixmap.h"
#include "src/gpu/ganesh/GrProcessorAnalysis.h"
#include "src/gpu/ganesh/GrProcessorSet.h"
#include "src/gpu/ganesh/GrProgramInfo.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrSimpleMesh.h"
#include "src/gpu/ganesh/GrUserStencilSettings.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/glsl/GrGLSLFragmentShaderBuilder.h"
#include "src/gpu/ganesh/glsl/GrGLSLVarying.h"
#include "src/gpu/ganesh/ops/GrMeshDrawOp.h"
#include "src/gpu/ganesh/ops/GrOp.h"
#include "src/gpu/ganesh/ops/GrSimpleMeshDrawOpHelper.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"

#include <algorithm>
#include <cstring>
#include <initializer_list>
#include <memory>
#include <string_view>
#include <utility>

class GrDstProxyView;
class GrGLSLProgramDataManager;
class GrRecordingContext;
class GrSurfaceProxyView;
class SkArenaAlloc;
enum class GrXferBarrierFlags;
namespace skgpu { class KeyBuilder; }
struct GrContextOptions;
struct GrShaderCaps;

// Simple op that draws a vertex buffer with float2 positions as green triangles. We use this to
// draw GrGpuBuffers to test that the buffer contains the expected values as not all contexts will
// support buffer mapping.
class TestVertexOp final : public GrMeshDrawOp {
public:
    static GrOp::Owner Make(GrRecordingContext* context,
                            sk_sp<GrGpuBuffer> buffer,
                            int baseVertex,
                            int vertexCount,
                            const SkRect& bounds) {
        return GrOp::Make<TestVertexOp>(context,
                                        std::move(buffer),
                                        baseVertex,
                                        vertexCount,
                                        bounds);
    }

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

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

    GrProcessorSet::Analysis finalize(const GrCaps& caps,
                                      const GrAppliedClip* clip,
                                      GrClampType clampType) override {
        static constexpr SkPMColor4f kGreen{0, 1, 0, 1};
        SkPMColor4f color = kGreen;
        auto analysis = fProcessorSet.finalize(GrProcessorAnalysisColor::Opaque::kYes,
                                               GrProcessorAnalysisCoverage::kNone,
                                               clip,
                                               &GrUserStencilSettings::kUnused,
                                               caps,
                                               clampType,
                                               &color);
        SkASSERT(color == kGreen);
        return analysis;
    }

    void visitProxies(const GrVisitProxyFunc& func) const override {
        if (fProgramInfo) {
            fProgramInfo->visitFPProxies(func);
        }
    }

private:
    DEFINE_OP_CLASS_ID

    TestVertexOp(sk_sp<GrGpuBuffer> buffer,
                 int baseVertex,
                 int vertexCount,
                 const SkRect& bounds)
                 : GrMeshDrawOp(ClassID())
                 , fBuffer(std::move(buffer))
                 , fProcessorSet(SkBlendMode::kSrc)
                 , fBaseVertex(baseVertex)
                 , fVertexCount(vertexCount) {
        this->setBounds(bounds, HasAABloat::kNo, GrOp::IsHairline::kNo);
     }

    GrProgramInfo* programInfo() override { return fProgramInfo; }

    void onCreateProgramInfo(const GrCaps* caps,
                             SkArenaAlloc* arena,
                             const GrSurfaceProxyView& writeView,
                             bool usesMSAASurface,
                             GrAppliedClip&& appliedClip,
                             const GrDstProxyView& dstProxyView,
                             GrXferBarrierFlags renderPassXferBarriers,
                             GrLoadOp colorLoadOp) override {
        fProgramInfo = GrSimpleMeshDrawOpHelper::CreateProgramInfo(
                caps,
                arena,
                writeView,
                usesMSAASurface,
                std::move(appliedClip),
                dstProxyView,
                &fGP,
                std::move(fProcessorSet),
                GrPrimitiveType::kTriangles,
                renderPassXferBarriers,
                colorLoadOp,
                GrPipeline::InputFlags::kNone);
    }

    class GP : public GrGeometryProcessor {
    public:
        GP() : GrGeometryProcessor(kTestFP_ClassID) {
            this->setVertexAttributesWithImplicitOffsets(&kPos, 1);
        }

        const char* name() const override { return "TestVertexOp::GP"; }

        std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override {
            class Impl : public ProgramImpl {
            public:
                void setData(const GrGLSLProgramDataManager&,
                             const GrShaderCaps&,
                             const GrGeometryProcessor&) override {}

            private:
                void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override {
                    const auto& gp = args.fGeomProc.cast<GP>();
                    args.fVaryingHandler->emitAttributes(gp);
                    args.fFragBuilder->codeAppendf("half4 %s = half4(0, 1, 0, 1);",
                                                   args.fOutputColor);
                    args.fFragBuilder->codeAppendf("const half4 %s = half4(1);",
                                                   args.fOutputCoverage);
                    WriteOutputPosition(args.fVertBuilder, gpArgs, kPos.name());
                }

                UniformHandle fLocalMatrixUni;
            };

            return std::make_unique<Impl>();
        }

        void addToKey(const GrShaderCaps &caps, skgpu::KeyBuilder *builder) const override {}

    private:
        static constexpr Attribute kPos = {"pos", kFloat2_GrVertexAttribType, SkSLType::kFloat2};
    };

    void onPrepareDraws(GrMeshDrawTarget* target) override {
        fMesh = target->allocMesh();
        fMesh->set(fBuffer, fVertexCount, fBaseVertex);
    }

    void onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) override {
        if (!fProgramInfo) {
            this->createProgramInfo(flushState);
        }

        flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds);
        flushState->bindTextures(fProgramInfo->geomProc(), nullptr, fProgramInfo->pipeline());
        flushState->drawMesh(*fMesh);
    }

    sk_sp<GrGpuBuffer> fBuffer;

    GP fGP;

    GrProcessorSet fProcessorSet;

    int fBaseVertex;
    int fVertexCount;

    GrProgramInfo* fProgramInfo = nullptr;
    GrSimpleMesh*  fMesh        = nullptr;

    friend class ::GrOp;
};

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrGpuBufferTransferTest,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    if (!ctxInfo.directContext()->priv().caps()->transferFromBufferToBufferSupport()) {
        return;
    }

    GrDirectContext* dc = ctxInfo.directContext();

    GrDrawingManager* dm = dc->priv().drawingManager();

    GrResourceProvider* rp = ctxInfo.directContext()->priv().resourceProvider();

    GrGpu* gpu = ctxInfo.directContext()->priv().getGpu();

    auto create_cpu_to_gpu_buffer = [&](int baseVertex) {
        // Ensure any extra vertices are offscreen
        int totalVertices = baseVertex + 6;
        auto points = std::make_unique<SkPoint[]>(totalVertices);
        SkPoint offscreenPt{-10000, -10000};
        std::fill_n(points.get(), totalVertices, offscreenPt);

        // set the quad at the desired base vertex
        static constexpr SkPoint kUnitQuad[] {{0, 0}, {0, 1}, {1, 0},
                                              {1, 0}, {0, 1}, {1, 1}};
        std::copy_n(kUnitQuad, 6, points.get() + baseVertex);

        return rp->createBuffer(points.get(),
                                totalVertices*sizeof(SkPoint),
                                GrGpuBufferType::kXferCpuToGpu,
                                kDynamic_GrAccessPattern);
    };

    auto create_vertex_buffer = [&](sk_sp<GrGpuBuffer> srcBuffer,
                                    int srcBaseVertex,
                                    int vbBaseVertex,
                                    bool useTask,
                                    bool minSizedTransfers) {
        // make initialization data of offscreen points.
        int dstVertexCount = vbBaseVertex + 6;
        auto points = std::make_unique<SkPoint[]>(dstVertexCount);
        SkPoint offscreenPt{-10000, -10000};
        std::fill_n(points.get(), dstVertexCount, offscreenPt);

        sk_sp<GrGpuBuffer> vb = rp->createBuffer(points.get(),
                                                 dstVertexCount*sizeof(SkPoint),
                                                 GrGpuBufferType::kVertex,
                                                 kDynamic_GrAccessPattern);

        // copy actual quad data from the source buffer to our new vb.

        static constexpr size_t kTotalSize = 6*sizeof(SkPoint);

        size_t srcOffset = srcBaseVertex*sizeof(SkPoint);
        size_t  vbOffset =  vbBaseVertex*sizeof(SkPoint);

        size_t alignment = gpu->caps()->transferFromBufferToBufferAlignment();
        SkASSERT(kTotalSize      % alignment == 0);
        SkASSERT(sizeof(SkPoint) % alignment == 0);

        if (minSizedTransfers) {
            for (size_t n = kTotalSize/alignment, i = 0; i < n; ++i) {
                if (useTask) {
                    dm->newBufferTransferTask(srcBuffer,
                                              srcOffset + i*alignment,
                                              vb,
                                              vbOffset + i*alignment,
                                              alignment);
                } else {
                    gpu->transferFromBufferToBuffer(srcBuffer,
                                                    srcOffset + i*alignment,
                                                    vb,
                                                    vbOffset + i*alignment,
                                                    alignment);
                }
            }
        } else if (useTask) {
            dm->newBufferTransferTask(srcBuffer, srcOffset, vb, vbOffset, kTotalSize);
        } else {
            gpu->transferFromBufferToBuffer(srcBuffer, srcOffset, vb, vbOffset, kTotalSize);
        }
        return vb;
    };

    auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dc,
                                                       GrColorType::kRGBA_8888,
                                                       nullptr,
                                                       SkBackingFit::kExact,
                                                       {1, 1},
                                                       SkSurfaceProps{},
                                                       std::string_view{});
    if (!sdc) {
        ERRORF(reporter, "Could not create draw context");
        return;
    }

    auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));

    for (bool useTask : {false, true}) {
        for (bool minSizedTransfers : {false, true}) {
            for (int srcBaseVertex : {0, 5}) {
                auto src = create_cpu_to_gpu_buffer(srcBaseVertex);
                if (!src) {
                    ERRORF(reporter, "Could not create src buffer");
                    return;
                }
                for (int vbBaseVertex : {0, 2}) {
                    auto vb = create_vertex_buffer(src,
                                                   srcBaseVertex,
                                                   vbBaseVertex,
                                                   useTask,
                                                   minSizedTransfers);
                    if (!vb) {
                        ERRORF(reporter, "Could not create vertex buffer");
                        return;
                    }

                    static constexpr SkColor4f kRed{1, 0, 0, 1};

                    static constexpr SkRect kBounds{0, 0, 1, 1};

                    sdc->clear(kRed);

                    sdc->addDrawOp(nullptr, TestVertexOp::Make(dc,
                                                               vb,
                                                               vbBaseVertex,
                                                               /*vertexCount=*/6,
                                                               kBounds));

                    auto color = static_cast<SkPMColor4f*>(pm.addr());
                    *color = kRed.premul();
                    if (!sdc->readPixels(dc, pm, {0, 0})) {
                        ERRORF(reporter, "Read back failed.");
                        return;
                    }

                    static constexpr SkPMColor4f kGreen{0, 1, 0, 1};

                    REPORTER_ASSERT(reporter, *color == kGreen, "src base vertex: %d, "
                                                                "vb base vertex: %d, "
                                                                "use task: %d, "
                                                                "minSizedTransfers: %d",
                                                                srcBaseVertex,
                                                                vbBaseVertex,
                                                                useTask,
                                                                minSizedTransfers);
                }
            }
        }
    }
}

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrGpuBufferUpdateDataTest,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    GrDirectContext* dc = ctxInfo.directContext();

    GrGpu* gpu = ctxInfo.directContext()->priv().getGpu();

    static constexpr SkPoint kUnitQuad[] {{0, 0}, {0, 1}, {1, 0},
                                          {1, 0}, {0, 1}, {1, 1}};

    auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(dc,
                                                       GrColorType::kRGBA_8888,
                                                       nullptr,
                                                       SkBackingFit::kExact,
                                                       {1, 1},
                                                       SkSurfaceProps{},
                                                       std::string_view{});
    if (!sdc) {
        ERRORF(reporter, "Could not create draw context");
        return;
    }

    auto pm = GrPixmap::Allocate(sdc->imageInfo().makeColorType(GrColorType::kRGBA_F32));

    for (bool piecewise : {false, true}) {
        size_t alignment = piecewise ? gpu->caps()->bufferUpdateDataPreserveAlignment() : 1;
        for (size_t offset : {size_t{0}, 4*sizeof(SkPoint), size_t{1}, size_t{27}}) {
            // For non-discarding updates we may not be able to actually put the data at an
            // arbitrary offset.
            if (alignment > 1) {
                offset = SkAlignTo(offset, alignment);
            }
            for (auto accessPattern : {kStatic_GrAccessPattern,
                                       //  kStream_GrAccessPattern, GrVkGpu asserts on this for VBs.
                                       kDynamic_GrAccessPattern}) {
                // Go direct to GrGpu to avoid caching/size adjustments at GrResourceProvider level.
                // We add an extra size(SkPoint) to ensure that everything fits when we align the
                // first point's location in the vb below.
                auto vb = gpu->createBuffer(sizeof(kUnitQuad) + offset + sizeof(SkPoint),
                                            GrGpuBufferType::kVertex,
                                            accessPattern);
                if (!vb) {
                    ERRORF(reporter, "Could not create vertex buffer");
                    return;
                }

                const void* src = kUnitQuad;
                size_t updateSize = sizeof(kUnitQuad);
                // The vertices in the VB must be aligned to the size of a vertex (because our draw
                // call takes a base vertex index rather than a byte offset). So if we want our
                // upload to begin at a non-aligned byte we shift the data in the src buffer so that
                // it falls at a vertex alignment in the vb.
                std::unique_ptr<char[]> tempSrc;
                size_t baseVertex = offset/sizeof(SkPoint);
                if (size_t r = offset%sizeof(SkPoint); r != 0) {
                    size_t pad = sizeof(SkPoint) - r;
                    updateSize += pad;
                    if (alignment > 1) {
                        updateSize = SkAlignTo(updateSize, alignment);
                    }
                    ++baseVertex;
                    tempSrc.reset(new char[updateSize]);
                    std::memcpy(tempSrc.get() + pad, kUnitQuad, sizeof(kUnitQuad));
                    src = tempSrc.get();
                }
                if (piecewise) {
                    // This is the minimum size we can transfer at once.
                    size_t pieceSize = alignment;

                    // Upload each piece from a buffer where the byte before and after the uploaded
                    // bytes are not the same values as want adjacent to the piece in the buffer.
                    // Thus, if updateData() transfers extra bytes around the source we should get a
                    // bad buffer.
                    auto piece = std::make_unique<unsigned char[]>(pieceSize + 2);
                    piece[0] = piece[pieceSize + 1] = 0xFF;

                    for (size_t o = 0; o < updateSize; o += pieceSize) {
                        memcpy(&piece[1], SkTAddOffset<const void>(src, o), pieceSize);
                        if (!vb->updateData(&piece[1], offset + o, pieceSize, /*preserve=*/true)) {
                            ERRORF(reporter, "GrGpuBuffer::updateData returned false.");
                            return;
                        }
                    }
                } else if (!vb->updateData(src, offset, updateSize, /*preserve=*/false)) {
                    ERRORF(reporter, "GrGpuBuffer::updateData returned false.");
                    return;
                }

                static constexpr SkColor4f kRed{1, 0, 0, 1};

                static constexpr SkRect kBounds{0, 0, 1, 1};

                sdc->clear(kRed);

                sdc->addDrawOp(nullptr, TestVertexOp::Make(dc,
                                                           vb,
                                                           baseVertex,
                                                           std::size(kUnitQuad),
                                                           kBounds));

                auto color = static_cast<SkPMColor4f*>(pm.addr());
                *color = kRed.premul();
                if (!sdc->readPixels(dc, pm, {0, 0})) {
                    ERRORF(reporter, "Read back failed.");
                    return;
                }

                static constexpr SkPMColor4f kGreen{0, 1, 0, 1};

                REPORTER_ASSERT(reporter, *color == kGreen, "piecewise: %d, offset: %zu",
                                piecewise, offset);
            }
        }
    }
}
