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

#include "GrColor.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrMeshDrawOp.h"
#include "GrOpFlushState.h"
#include "GrRectOpFactory.h"
#include "GrResourceKey.h"
#include "GrResourceProvider.h"
#include "GrTypes.h"
#include "SkMatrix.h"
#include "SkMatrixPriv.h"
#include "SkRect.h"
#include "SkPointPriv.h"
#include "ops/GrSimpleMeshDrawOpHelper.h"
#include <new>

GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);

static inline bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) {
    return viewMatrix.preservesRightAngles();
}

static inline void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx,
                                 SkScalar dy) {
    SkPointPriv::SetRectFan(pts, r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride);
}

static const int kNumAAFillRectsInIndexBuffer = 256;
static const int kVertsPerAAFillRect = 8;
static const int kIndicesPerAAFillRect = 30;

static sk_sp<const GrBuffer> get_index_buffer(GrResourceProvider* resourceProvider) {
    GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);

    // clang-format off
    static const uint16_t gFillAARectIdx[] = {
        0, 1, 5, 5, 4, 0,
        1, 2, 6, 6, 5, 1,
        2, 3, 7, 7, 6, 2,
        3, 0, 4, 4, 7, 3,
        4, 5, 6, 6, 7, 4,
    };
    // clang-format on

    GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect);
    return resourceProvider->findOrCreatePatternedIndexBuffer(
            gFillAARectIdx, kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer,
            kVertsPerAAFillRect, gAAFillRectIndexBufferKey);
}

static void generate_aa_fill_rect_geometry(intptr_t verts,
                                           size_t vertexStride,
                                           GrColor color,
                                           const SkMatrix& viewMatrix,
                                           const SkRect& rect,
                                           const SkRect& devRect,
                                           bool tweakAlphaForCoverage,
                                           const SkMatrix* localMatrix) {
    SkPoint* fan0Pos = reinterpret_cast<SkPoint*>(verts);
    SkPoint* fan1Pos = reinterpret_cast<SkPoint*>(verts + 4 * vertexStride);

    SkScalar inset;

    if (viewMatrix.rectStaysRect()) {
        inset = SkMinScalar(devRect.width(), SK_Scalar1);
        inset = SK_ScalarHalf * SkMinScalar(inset, devRect.height());

        set_inset_fan(fan0Pos, vertexStride, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
        set_inset_fan(fan1Pos, vertexStride, devRect, inset, inset);
    } else {
        // compute transformed (1, 0) and (0, 1) vectors
        SkVector vec[2] = {{viewMatrix[SkMatrix::kMScaleX], viewMatrix[SkMatrix::kMSkewY]},
                           {viewMatrix[SkMatrix::kMSkewX], viewMatrix[SkMatrix::kMScaleY]}};

        SkScalar len1 = SkPoint::Normalize(&vec[0]);
        vec[0].scale(SK_ScalarHalf);
        SkScalar len2 = SkPoint::Normalize(&vec[1]);
        vec[1].scale(SK_ScalarHalf);

        inset = SkMinScalar(len1 * rect.width(), SK_Scalar1);
        inset = SK_ScalarHalf * SkMinScalar(inset, len2 * rect.height());

        // create the rotated rect
        SkPointPriv::SetRectFan(fan0Pos, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom,
                vertexStride);
        SkMatrixPriv::MapPointsWithStride(viewMatrix, fan0Pos, vertexStride, 4);

        // Now create the inset points and then outset the original
        // rotated points

        // TL
        *((SkPoint*)((intptr_t)fan1Pos + 0 * vertexStride)) =
                *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) + vec[0] + vec[1];
        *((SkPoint*)((intptr_t)fan0Pos + 0 * vertexStride)) -= vec[0] + vec[1];
        // BL
        *((SkPoint*)((intptr_t)fan1Pos + 1 * vertexStride)) =
                *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) + vec[0] - vec[1];
        *((SkPoint*)((intptr_t)fan0Pos + 1 * vertexStride)) -= vec[0] - vec[1];
        // BR
        *((SkPoint*)((intptr_t)fan1Pos + 2 * vertexStride)) =
                *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) - vec[0] - vec[1];
        *((SkPoint*)((intptr_t)fan0Pos + 2 * vertexStride)) += vec[0] + vec[1];
        // TR
        *((SkPoint*)((intptr_t)fan1Pos + 3 * vertexStride)) =
                *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) - vec[0] + vec[1];
        *((SkPoint*)((intptr_t)fan0Pos + 3 * vertexStride)) += vec[0] - vec[1];
    }

    if (localMatrix) {
        SkMatrix invViewMatrix;
        if (!viewMatrix.invert(&invViewMatrix)) {
            SkDebugf("View matrix is non-invertible, local coords will be wrong.");
            invViewMatrix = SkMatrix::I();
        }
        SkMatrix localCoordMatrix;
        localCoordMatrix.setConcat(*localMatrix, invViewMatrix);
        SkPoint* fan0Loc = reinterpret_cast<SkPoint*>(verts + sizeof(SkPoint) + sizeof(GrColor));
        SkMatrixPriv::MapPointsWithStride(localCoordMatrix, fan0Loc, vertexStride, fan0Pos,
                                          vertexStride, 8);
    }

    // Make verts point to vertex color and then set all the color and coverage vertex attrs
    // values.
    verts += sizeof(SkPoint);

    // The coverage offset is always the last vertex attribute
    intptr_t coverageOffset = vertexStride - sizeof(GrColor) - sizeof(SkPoint);
    for (int i = 0; i < 4; ++i) {
        if (tweakAlphaForCoverage) {
            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = 0;
        } else {
            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
            *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = 0;
        }
    }

    int scale;
    if (inset < SK_ScalarHalf) {
        scale = SkScalarFloorToInt(512.0f * inset / (inset + SK_ScalarHalf));
        SkASSERT(scale >= 0 && scale <= 255);
    } else {
        scale = 0xff;
    }

    verts += 4 * vertexStride;

    float innerCoverage = GrNormalizeByteToFloat(scale);
    GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, scale);

    for (int i = 0; i < 4; ++i) {
        if (tweakAlphaForCoverage) {
            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor;
        } else {
            *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color;
            *reinterpret_cast<float*>(verts + i * vertexStride + coverageOffset) = innerCoverage;
        }
    }
}

namespace {

class AAFillRectOp final : public GrMeshDrawOp {
private:
    using Helper = GrSimpleMeshDrawOpHelperWithStencil;

public:
    DEFINE_OP_CLASS_ID

    static std::unique_ptr<GrDrawOp> Make(GrContext* context,
                                          GrPaint&& paint,
                                          const SkMatrix& viewMatrix,
                                          const SkRect& rect,
                                          const SkRect& devRect,
                                          const SkMatrix* localMatrix,
                                          const GrUserStencilSettings* stencil) {
        SkASSERT(view_matrix_ok_for_aa_fill_rect(viewMatrix));
        return Helper::FactoryHelper<AAFillRectOp>(context, std::move(paint), viewMatrix, rect,
                                                   devRect, localMatrix, stencil);
    }

    AAFillRectOp(const Helper::MakeArgs& helperArgs,
                 const SkPMColor4f& color,
                 const SkMatrix& viewMatrix,
                 const SkRect& rect,
                 const SkRect& devRect,
                 const SkMatrix* localMatrix,
                 const GrUserStencilSettings* stencil)
            : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage, stencil) {
        if (localMatrix) {
            void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo));
            new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix);
        } else {
            void* mem = fRectData.push_back_n(sizeof(RectInfo));
            new (mem) RectInfo(color, viewMatrix, rect, devRect);
        }
        IsZeroArea zeroArea =
                (!rect.width() || !rect.height()) ? IsZeroArea::kYes : IsZeroArea::kNo;
        this->setBounds(devRect, HasAABloat::kYes, zeroArea);
        fRectCnt = 1;
    }

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

    void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
        fHelper.visitProxies(func);
    }

#ifdef SK_DEBUG
    SkString dumpInfo() const override {
        SkString str;
        str.append(INHERITED::dumpInfo());
        str.appendf("# combined: %d\n", fRectCnt);
        const RectInfo* info = this->first();
        for (int i = 0; i < fRectCnt; ++i) {
            const SkRect& rect = info->rect();
            str.appendf("%d: Color: 0x%08x, Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]\n", i,
                        info->color().toBytes_RGBA(), rect.fLeft, rect.fTop, rect.fRight,
                        rect.fBottom);
            info = this->next(info);
        }
        str += fHelper.dumpInfo();
        str += INHERITED::dumpInfo();
        return str;
    }
#endif

    FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }

    RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
        SkPMColor4f color = this->first()->color();
        auto result = fHelper.xpRequiresDstTexture(
                caps, clip, GrProcessorAnalysisCoverage::kSingleChannel, &color);
        this->first()->setColor(color);
        return result;
    }

private:
    void onPrepareDraws(Target* target) override {
        using namespace GrDefaultGeoProcFactory;

        Color color(Color::kPremulGrColorAttribute_Type);
        Coverage::Type coverageType = Coverage::kSolid_Type;
        if (!fHelper.compatibleWithAlphaAsCoverage()) {
            coverageType = Coverage::kAttribute_Type;
        }
        LocalCoords lc = LocalCoords::kUnused_Type;
        if (fHelper.usesLocalCoords()) {
            lc = LocalCoords::kHasExplicit_Type;
        }

        sk_sp<GrGeometryProcessor> gp =
                GrDefaultGeoProcFactory::Make(target->caps().shaderCaps(), color, coverageType,
                                              lc, SkMatrix::I());
        if (!gp) {
            SkDebugf("Couldn't create GrGeometryProcessor\n");
            return;
        }

        size_t vertexStride = gp->vertexStride();

        sk_sp<const GrBuffer> indexBuffer = get_index_buffer(target->resourceProvider());
        PatternHelper helper(target, GrPrimitiveType::kTriangles, vertexStride, indexBuffer.get(),
                             kVertsPerAAFillRect, kIndicesPerAAFillRect, fRectCnt);
        void* vertices = helper.vertices();
        if (!vertices || !indexBuffer) {
            SkDebugf("Could not allocate vertices\n");
            return;
        }

        const RectInfo* info = this->first();
        const SkMatrix* localMatrix = nullptr;
        for (int i = 0; i < fRectCnt; i++) {
            intptr_t verts =
                    reinterpret_cast<intptr_t>(vertices) + i * kVertsPerAAFillRect * vertexStride;
            if (fHelper.usesLocalCoords()) {
                if (info->hasLocalMatrix()) {
                    localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(info)->localMatrix();
                } else {
                    localMatrix = &SkMatrix::I();
                }
            }
            // TODO4F: Preserve float colors
            generate_aa_fill_rect_geometry(verts, vertexStride, info->color().toBytes_RGBA(),
                                           info->viewMatrix(), info->rect(), info->devRect(),
                                           fHelper.compatibleWithAlphaAsCoverage(), localMatrix);
            info = this->next(info);
        }
        auto pipe = fHelper.makePipeline(target);
        helper.recordDraw(target, std::move(gp), pipe.fPipeline, pipe.fFixedDynamicState);
    }

    CombineResult onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
        AAFillRectOp* that = t->cast<AAFillRectOp>();
        if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
            return CombineResult::kCannotCombine;
        }

        fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin());
        fRectCnt += that->fRectCnt;
        return CombineResult::kMerged;
    }

    struct RectInfo {
    public:
        RectInfo(const SkPMColor4f& color, const SkMatrix& viewMatrix, const SkRect& rect,
                 const SkRect& devRect)
                : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kNo) {}
        bool hasLocalMatrix() const { return HasLocalMatrix::kYes == fHasLocalMatrix; }
        const SkPMColor4f& color() const { return fColor; }
        const SkMatrix& viewMatrix() const { return fViewMatrix; }
        const SkRect& rect() const { return fRect; }
        const SkRect& devRect() const { return fDevRect; }

        void setColor(const SkPMColor4f& color) { fColor = color; }

    protected:
        enum class HasLocalMatrix : uint32_t { kNo, kYes };

        RectInfo(const SkPMColor4f& color, const SkMatrix& viewMatrix, const SkRect& rect,
                 const SkRect& devRect, HasLocalMatrix hasLM)
                : fHasLocalMatrix(hasLM)
                , fColor(color)
                , fViewMatrix(viewMatrix)
                , fRect(rect)
                , fDevRect(devRect) {}

        HasLocalMatrix fHasLocalMatrix;
        SkPMColor4f fColor;
        SkMatrix fViewMatrix;
        SkRect fRect;
        SkRect fDevRect;
    };

    struct RectWithLocalMatrixInfo : public RectInfo {
    public:
        RectWithLocalMatrixInfo(const SkPMColor4f& color, const SkMatrix& viewMatrix,
                                const SkRect& rect, const SkRect& devRect,
                                const SkMatrix& localMatrix)
                : RectInfo(color, viewMatrix, rect, devRect, HasLocalMatrix::kYes)
                , fLocalMatrix(localMatrix) {}
        const SkMatrix& localMatrix() const { return fLocalMatrix; }

    private:
        SkMatrix fLocalMatrix;
    };

    RectInfo* first() { return reinterpret_cast<RectInfo*>(fRectData.begin()); }
    const RectInfo* first() const { return reinterpret_cast<const RectInfo*>(fRectData.begin()); }
    const RectInfo* next(const RectInfo* prev) const {
        intptr_t next =
                reinterpret_cast<intptr_t>(prev) +
                (prev->hasLocalMatrix() ? sizeof(RectWithLocalMatrixInfo) : sizeof(RectInfo));
        return reinterpret_cast<const RectInfo*>(next);
    }

    SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData;
    Helper fHelper;
    int fRectCnt;

    typedef GrMeshDrawOp INHERITED;
};

}  // anonymous namespace

namespace GrRectOpFactory {

std::unique_ptr<GrDrawOp> MakeAAFill(GrContext* context,
                                     GrPaint&& paint,
                                     const SkMatrix& viewMatrix,
                                     const SkRect& rect,
                                     const GrUserStencilSettings* stencil) {
    if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
        return nullptr;
    }
    SkRect devRect;
    viewMatrix.mapRect(&devRect, rect);
    return AAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, devRect,
                              nullptr, stencil);
}

std::unique_ptr<GrDrawOp> MakeAAFillWithLocalMatrix(GrContext* context,
                                                    GrPaint&& paint,
                                                    const SkMatrix& viewMatrix,
                                                    const SkMatrix& localMatrix,
                                                    const SkRect& rect) {
    if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
        return nullptr;
    }
    SkRect devRect;
    viewMatrix.mapRect(&devRect, rect);
    return AAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, devRect,
                              &localMatrix, nullptr);
}

std::unique_ptr<GrDrawOp> MakeAAFillWithLocalRect(GrContext* context,
                                                  GrPaint&& paint,
                                                  const SkMatrix& viewMatrix,
                                                  const SkRect& rect,
                                                  const SkRect& localRect) {
    if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
        return nullptr;
    }
    SkRect devRect;
    viewMatrix.mapRect(&devRect, rect);
    SkMatrix localMatrix;
    if (!localMatrix.setRectToRect(rect, localRect, SkMatrix::kFill_ScaleToFit)) {
        return nullptr;
    }
    return AAFillRectOp::Make(context, std::move(paint), viewMatrix, rect, devRect,
                              &localMatrix, nullptr);
}

}  // namespace GrRectOpFactory

///////////////////////////////////////////////////////////////////////////////////////////////////

#if GR_TEST_UTILS

#include "GrDrawOpTest.h"

GR_DRAW_OP_TEST_DEFINE(AAFillRectOp) {
    SkMatrix viewMatrix;
    do {
        viewMatrix = GrTest::TestMatrixInvertible(random);
    } while (!view_matrix_ok_for_aa_fill_rect(viewMatrix));
    SkRect rect = GrTest::TestRect(random);
    SkRect devRect;
    viewMatrix.mapRect(&devRect, rect);
    const SkMatrix* localMatrix = nullptr;
    SkMatrix m;
    if (random->nextBool()) {
        m = GrTest::TestMatrix(random);
    }
    const GrUserStencilSettings* stencil = random->nextBool() ? nullptr
                                                              : GrGetRandomStencil(random, context);
    return AAFillRectOp::Make(context, std::move(paint), viewMatrix, rect,
                              devRect, localMatrix, stencil);
}

#endif
