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

#include "tests/Test.h"

#include "src/gpu/GrRenderTargetContext.h"
#include "src/gpu/GrRenderTargetContextPriv.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"

static void run_test(skiatest::Reporter*, GrDirectContext*, GrRenderTargetContext*, SkVector a,
                     SkVector b, float expectedCrossProduct);

// This is a GPU test that ensures the SkSL 2d cross() intrinsic returns the correct sign (negative,
// positive, or zero).
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkSLCross, reporter, ctxInfo) {
    GrDirectContext* directContext = ctxInfo.directContext();
    auto rtc = GrRenderTargetContext::Make(directContext, GrColorType::kRGBA_8888, nullptr,
                                           SkBackingFit::kExact, {1, 1});
    if (!rtc) {
        ERRORF(reporter, "could not create render target context.");
        return;
    }
    run_test(reporter, directContext, rtc.get(), {3,4}, {5,6}, -2);  // Negative.
    run_test(reporter, directContext, rtc.get(), {3,4}, {-5,-6}, 2);  // Positive.
    run_test(reporter, directContext, rtc.get(), {0, 2.287f}, {0, -7.741f}, 0);  // Zero.
    run_test(reporter, directContext, rtc.get(), {62.17f, 0}, {-43.49f, 0}, 0);  // Zero.
}

namespace {

// Outputs:
//     Green if cross(a,b) > 0
//     Red if cross(a,b) < 0
//     Black if cross(a,b) == 0
class VisualizeCrossProductSignFP : public GrFragmentProcessor {
public:
    VisualizeCrossProductSignFP(SkVector a, SkVector b)
            : GrFragmentProcessor(kTestFP_ClassID, kPreservesOpaqueInput_OptimizationFlag)
            , fA(a), fB(b) {
    }

private:
    const char* name() const override { return "VisualizeCrossProductSignFP"; }
    std::unique_ptr<GrFragmentProcessor> clone() const override {
        return std::unique_ptr<GrFragmentProcessor>(new VisualizeCrossProductSignFP(fA, fB));
    }
    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}
    bool onIsEqual(const GrFragmentProcessor&) const override { return true; }

    class Impl : public GrGLSLFragmentProcessor {
        void emitCode(EmitArgs& args) override {
            auto& fp = args.fFp.cast<VisualizeCrossProductSignFP>();
            const char* a, *b;
            fAUniform = args.fUniformHandler->addUniform(&fp, kFragment_GrShaderFlag,
                                                         GrSLType::kFloat2_GrSLType, "a", &a);
            fBUniform = args.fUniformHandler->addUniform(&fp, kFragment_GrShaderFlag,
                                                         GrSLType::kFloat2_GrSLType, "b", &b);
            args.fFragBuilder->codeAppendf(R"(
                    float crossProduct = cross(%s, %s);
                    float2 visualization = clamp(float2(-sign(crossProduct), sign(crossProduct)),
                                                 float2(0), float2(1));
                    %s = half4(half2(visualization), 0, 1);)", a, b, args.fOutputColor);
        }
        void onSetData(const GrGLSLProgramDataManager& pdman,
                       const GrFragmentProcessor& processor) override {
            const auto& fp = processor.cast<VisualizeCrossProductSignFP>();
            pdman.set2f(fAUniform, fp.fA.x(), fp.fA.y());
            pdman.set2f(fBUniform, fp.fB.x(), fp.fB.y());
        }
        GrGLSLUniformHandler::UniformHandle fAUniform;
        GrGLSLUniformHandler::UniformHandle fBUniform;
    };

    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { return new Impl; }
    const SkVector fA, fB;
};

}  // namespace

static void run_test(skiatest::Reporter* reporter, GrDirectContext* directContext,
                     GrRenderTargetContext* rtc, SkVector a, SkVector b,
                     float expectedCrossProduct) {
    SkASSERT(rtc->width() == 1);
    SkASSERT(rtc->height() == 1);

    rtc->clear(SkPMColor4f::FromBytes_RGBA(0xbaaaaaad));

    GrPaint crossPaint;
    crossPaint.setColor4f(SK_PMColor4fWHITE);
    crossPaint.setPorterDuffXPFactory(SkBlendMode::kSrcOver);
    crossPaint.setColorFragmentProcessor(std::make_unique<VisualizeCrossProductSignFP>(a, b));
    rtc->drawRect(/*clip=*/nullptr, std::move(crossPaint), GrAA::kNo, SkMatrix::I(),
                  SkRect::MakeWH(1,1));

    GrColor result;
    rtc->readPixels(directContext,
                    SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType), &result,
                    4, {0, 0});

    SkASSERT(expectedCrossProduct == a.cross(b));
    if (expectedCrossProduct > 0) {
        REPORTER_ASSERT(reporter, result == GrColorPackRGBA(0, 255, 0, 255));  // Green.
    } else if (expectedCrossProduct < 0) {
        REPORTER_ASSERT(reporter, result == GrColorPackRGBA(255, 0, 0, 255));  // Red.
    } else {
        REPORTER_ASSERT(reporter, result == GrColorPackRGBA(0, 0, 0, 255));  // Black.
    }
}
