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

// This test only works with the Ganesh backend.

#include "gm/gm.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/core/SkCanvasPriv.h"
#include "src/gpu/ganesh/GrCanvas.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/effects/GrPorterDuffXferProcessor.h"
#include "tools/ganesh/TestOps.h"

#include <memory>
#include <utility>

class GrAppliedClip;

namespace skiagm {

/**
 * This GM directly exercises a GrProcessor that clips against rects.
 */
class AARectEffect : public GpuGM {
public:
    AARectEffect() { this->setBGColor(0xFFFFFFFF); }

protected:
    SkString getName() const override { return SkString("aa_rect_effect"); }

    SkISize getISize() override { return SkISize::Make(210, 250); }

    void onOnceBeforeDraw() override {}

    DrawResult onDraw(GrRecordingContext* rContext, SkCanvas* canvas, SkString* errorMsg) override {
        auto sdc = skgpu::ganesh::TopDeviceSurfaceDrawContext(canvas);
        if (!sdc) {
            *errorMsg = kErrorMsg_DrawSkippedGpuOnly;
            return DrawResult::kSkip;
        }

        SkScalar y = 12.f;
        static constexpr SkScalar kDX = 12.f;
        static constexpr SkScalar kOutset = 5.f;

        static constexpr SkRect kRects[] = {
                // integer edges
                SkRect::MakeLTRB(5.f, 1.f, 30.f, 25.f),
                // half-integer edges
                SkRect::MakeLTRB(5.5f, 0.5f, 29.5f, 24.5f),
                // vertically/horizontally thin rects that cover pixel centers
                SkRect::MakeLTRB(5.25f, 0.5f, 5.75f, 24.5f),
                SkRect::MakeLTRB(5.5f,  0.5f, 29.5f, 0.75f),
                // vertically/horizontally thin rects that don't cover pixel centers
                SkRect::MakeLTRB(5.55f, 0.5f, 5.75f, 24.5f),
                SkRect::MakeLTRB(5.5f, .05f, 29.5f, .25f),
                // small in x and y
                SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f),
        };

        for (auto r : kRects) {
            SkScalar x = kDX;

            for (int et = 0; et < kGrClipEdgeTypeCnt; ++et) {
                SkRect rect = r.makeOffset(x, y);
                GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(et);
                auto fp = GrFragmentProcessor::Rect(/*inputFP=*/nullptr, edgeType, rect);
                SkASSERT(fp);

                GrPaint grPaint;
                grPaint.setColor4f({ 0, 0, 0, 1.f });
                grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
                grPaint.setCoverageFragmentProcessor(std::move(fp));
                auto drawRect = rect.makeOutset(kOutset, kOutset);
                auto op = sk_gpu_test::test_ops::MakeRect(rContext, std::move(grPaint), drawRect);
                sdc->addDrawOp(std::move(op));

                x += SkScalarCeilToScalar(rect.width() + kDX);
            }

            // Draw rect without and with AA using normal API for reference
            canvas->save();
            canvas->translate(x, y);
            SkPaint paint;
            canvas->drawRect(r, paint);
            x += SkScalarCeilToScalar(r.width() + kDX);
            paint.setAntiAlias(true);
            canvas->drawRect(r, paint);
            canvas->restore();

            y += SkScalarCeilToScalar(r.height() + 20.f);
        }

        return DrawResult::kOk;
    }

private:
    using INHERITED = GM;
};

DEF_GM(return new AARectEffect;)
}  // namespace skiagm
