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

#include "src/gpu/GrStyle.h"
#include "src/gpu/gl/GrGLGpu.h"
#include "src/gpu/gl/GrGLPath.h"
#include "src/gpu/gl/GrGLPathRendering.h"

namespace {
inline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) {
    static const GrGLubyte gTable[] = {
        GR_GL_MOVE_TO,
        GR_GL_LINE_TO,
        GR_GL_QUADRATIC_CURVE_TO,
        GR_GL_CONIC_CURVE_TO,
        GR_GL_CUBIC_CURVE_TO,
        GR_GL_CLOSE_PATH,
    };
    GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
    GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
    GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
    GR_STATIC_ASSERT(3 == SkPath::kConic_Verb);
    GR_STATIC_ASSERT(4 == SkPath::kCubic_Verb);
    GR_STATIC_ASSERT(5 == SkPath::kClose_Verb);

    SkASSERT(verb >= 0 && (size_t)verb < SK_ARRAY_COUNT(gTable));
    return gTable[verb];
}

#ifdef SK_DEBUG
inline int num_coords(SkPath::Verb verb) {
    static const int gTable[] = {
        2, // move
        2, // line
        4, // quad
        5, // conic
        6, // cubic
        0, // close
    };
    GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
    GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
    GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
    GR_STATIC_ASSERT(3 == SkPath::kConic_Verb);
    GR_STATIC_ASSERT(4 == SkPath::kCubic_Verb);
    GR_STATIC_ASSERT(5 == SkPath::kClose_Verb);

    SkASSERT(verb >= 0 && (size_t)verb < SK_ARRAY_COUNT(gTable));
    return gTable[verb];
}
#endif

inline GrGLenum join_to_gl_join(SkPaint::Join join) {
    static GrGLenum gSkJoinsToGrGLJoins[] = {
        GR_GL_MITER_REVERT,
        GR_GL_ROUND,
        GR_GL_BEVEL
    };
    return gSkJoinsToGrGLJoins[join];
    GR_STATIC_ASSERT(0 == SkPaint::kMiter_Join);
    GR_STATIC_ASSERT(1 == SkPaint::kRound_Join);
    GR_STATIC_ASSERT(2 == SkPaint::kBevel_Join);
    GR_STATIC_ASSERT(SK_ARRAY_COUNT(gSkJoinsToGrGLJoins) == SkPaint::kJoinCount);
}

inline GrGLenum cap_to_gl_cap(SkPaint::Cap cap) {
    static GrGLenum gSkCapsToGrGLCaps[] = {
        GR_GL_FLAT,
        GR_GL_ROUND,
        GR_GL_SQUARE
    };
    return gSkCapsToGrGLCaps[cap];
    GR_STATIC_ASSERT(0 == SkPaint::kButt_Cap);
    GR_STATIC_ASSERT(1 == SkPaint::kRound_Cap);
    GR_STATIC_ASSERT(2 == SkPaint::kSquare_Cap);
    GR_STATIC_ASSERT(SK_ARRAY_COUNT(gSkCapsToGrGLCaps) == SkPaint::kCapCount);
}

#ifdef SK_DEBUG
inline void verify_floats(const float* floats, int count) {
    for (int i = 0; i < count; ++i) {
        SkASSERT(!SkScalarIsNaN(SkFloatToScalar(floats[i])));
    }
}
#endif

inline void points_to_coords(const SkPoint points[], size_t first_point, size_t amount,
                             GrGLfloat coords[]) {
    for (size_t i = 0;  i < amount; ++i) {
        coords[i * 2] =  SkScalarToFloat(points[first_point + i].fX);
        coords[i * 2 + 1] = SkScalarToFloat(points[first_point + i].fY);
    }
}

template<bool checkForDegenerates>
inline bool init_path_object_for_general_path(GrGLGpu* gpu, GrGLuint pathID,
                                              const SkPath& skPath) {
    SkDEBUGCODE(int numCoords = 0);
    int verbCnt = skPath.countVerbs();
    int pointCnt = skPath.countPoints();
    int minCoordCnt = pointCnt * 2;

    SkSTArray<16, GrGLubyte, true> pathCommands(verbCnt);
    SkSTArray<16, GrGLfloat, true> pathCoords(minCoordCnt);
    bool lastVerbWasMove = true; // A path with just "close;" means "moveto(0,0); close;"
    SkPoint points[4];
    SkPath::RawIter iter(skPath);
    SkPath::Verb verb;
    while ((verb = iter.next(points)) != SkPath::kDone_Verb) {
        pathCommands.push_back(verb_to_gl_path_cmd(verb));
        GrGLfloat coords[6];
        int coordsForVerb;
        switch (verb) {
            case SkPath::kMove_Verb:
                if (checkForDegenerates) {
                    lastVerbWasMove = true;
                }
                points_to_coords(points, 0, 1, coords);
                coordsForVerb = 2;
                break;
            case SkPath::kLine_Verb:
                if (checkForDegenerates) {
                    if (SkPath::IsLineDegenerate(points[0], points[1], true)) {
                        return false;
                    }
                    lastVerbWasMove = false;
                }

                points_to_coords(points, 1, 1, coords);
                coordsForVerb = 2;
                break;
            case SkPath::kConic_Verb:
                if (checkForDegenerates) {
                    if (SkPath::IsQuadDegenerate(points[0], points[1], points[2], true)) {
                        return false;
                    }
                    lastVerbWasMove = false;
                }
                points_to_coords(points, 1, 2, coords);
                coords[4] = SkScalarToFloat(iter.conicWeight());
                coordsForVerb = 5;
                break;
            case SkPath::kQuad_Verb:
                if (checkForDegenerates) {
                    if (SkPath::IsQuadDegenerate(points[0], points[1], points[2], true)) {
                        return false;
                    }
                    lastVerbWasMove = false;
                }
                points_to_coords(points, 1, 2, coords);
                coordsForVerb = 4;
                break;
            case SkPath::kCubic_Verb:
                if (checkForDegenerates) {
                    if (SkPath::IsCubicDegenerate(points[0], points[1], points[2], points[3],
                                                  true)) {
                        return false;
                    }
                    lastVerbWasMove = false;
                }
                points_to_coords(points, 1, 3, coords);
                coordsForVerb = 6;
                break;
            case SkPath::kClose_Verb:
                if (checkForDegenerates) {
                    if (lastVerbWasMove) {
                        // Interpret "move(x,y);close;" as "move(x,y);lineto(x,y);close;".
                        // which produces a degenerate segment.
                        return false;
                    }
                }
                continue;
            default:
                SkASSERT(false);  // Not reached.
                continue;
        }
        SkDEBUGCODE(numCoords += num_coords(verb));
        SkDEBUGCODE(verify_floats(coords, coordsForVerb));
        pathCoords.push_back_n(coordsForVerb, coords);
    }
    SkASSERT(verbCnt == pathCommands.count());
    SkASSERT(numCoords == pathCoords.count());

    GR_GL_CALL(gpu->glInterface(),
               PathCommands(pathID, pathCommands.count(), pathCommands.begin(),
                            pathCoords.count(), GR_GL_FLOAT, pathCoords.begin()));
    return true;
}

/*
 * For now paths only natively support winding and even odd fill types
 */
static GrPathRendering::FillType convert_skpath_filltype(SkPath::FillType fill) {
    switch (fill) {
        default:
            SK_ABORT("Incomplete Switch\n");
        case SkPath::kWinding_FillType:
        case SkPath::kInverseWinding_FillType:
            return GrPathRendering::kWinding_FillType;
        case SkPath::kEvenOdd_FillType:
        case SkPath::kInverseEvenOdd_FillType:
            return GrPathRendering::kEvenOdd_FillType;
    }
}

} // namespace

bool GrGLPath::InitPathObjectPathDataCheckingDegenerates(GrGLGpu* gpu, GrGLuint pathID,
                                                         const SkPath& skPath) {
    return init_path_object_for_general_path<true>(gpu, pathID, skPath);
}

void GrGLPath::InitPathObjectPathData(GrGLGpu* gpu,
                                      GrGLuint pathID,
                                      const SkPath& skPath) {
    SkASSERT(!skPath.isEmpty());

#if 1  //  SK_SCALAR_IS_FLOAT
    // This branch does type punning, converting SkPoint* to GrGLfloat*.
    if ((skPath.getSegmentMasks() & SkPath::kConic_SegmentMask) == 0) {
        int verbCnt = skPath.countVerbs();
        int pointCnt = skPath.countPoints();
        int coordCnt = pointCnt * 2;
        SkSTArray<16, GrGLubyte, true> pathCommands(verbCnt);
        SkSTArray<16, GrGLfloat, true> pathCoords(coordCnt);

        static_assert(sizeof(SkPoint) == sizeof(GrGLfloat) * 2, "sk_point_not_two_floats");

        pathCommands.resize_back(verbCnt);
        pathCoords.resize_back(coordCnt);
        skPath.getPoints(reinterpret_cast<SkPoint*>(&pathCoords[0]), pointCnt);
        skPath.getVerbs(&pathCommands[0], verbCnt);

        SkDEBUGCODE(int verbCoordCnt = 0);
        for (int i = 0; i < verbCnt; ++i) {
            SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
            pathCommands[i] = verb_to_gl_path_cmd(v);
            SkDEBUGCODE(verbCoordCnt += num_coords(v));
        }
        SkASSERT(verbCnt == pathCommands.count());
        SkASSERT(verbCoordCnt == pathCoords.count());
        SkDEBUGCODE(verify_floats(&pathCoords[0], pathCoords.count()));
        GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, pathCommands.count(), &pathCommands[0],
                                                    pathCoords.count(), GR_GL_FLOAT,
                                                    &pathCoords[0]));
        return;
    }
#endif
    SkAssertResult(init_path_object_for_general_path<false>(gpu, pathID, skPath));
}

void GrGLPath::InitPathObjectStroke(GrGLGpu* gpu, GrGLuint pathID, const SkStrokeRec& stroke) {
    SkASSERT(!stroke.isHairlineStyle());
    GR_GL_CALL(gpu->glInterface(),
               PathParameterf(pathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(stroke.getWidth())));
    GR_GL_CALL(gpu->glInterface(),
               PathParameterf(pathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(stroke.getMiter())));
    GrGLenum join = join_to_gl_join(stroke.getJoin());
    GR_GL_CALL(gpu->glInterface(), PathParameteri(pathID, GR_GL_PATH_JOIN_STYLE, join));
    GrGLenum cap = cap_to_gl_cap(stroke.getCap());
    GR_GL_CALL(gpu->glInterface(), PathParameteri(pathID, GR_GL_PATH_END_CAPS, cap));
    GR_GL_CALL(gpu->glInterface(), PathParameterf(pathID, GR_GL_PATH_STROKE_BOUND, 0.02f));
}

void GrGLPath::InitPathObjectEmptyPath(GrGLGpu* gpu, GrGLuint pathID) {
    GR_GL_CALL(gpu->glInterface(), PathCommands(pathID, 0, nullptr, 0, GR_GL_FLOAT, nullptr));
}

GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStyle& style)
    : INHERITED(gpu, origSkPath, style),
      fPathID(gpu->glPathRendering()->genPaths(1)) {

    if (origSkPath.isEmpty()) {
        InitPathObjectEmptyPath(gpu, fPathID);
        fShouldStroke = false;
        fShouldFill = false;
    } else {
        const SkPath* skPath = &origSkPath;
        SkTLazy<SkPath> tmpPath;
        SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);

        if (style.pathEffect()) {
            // Skia stroking and NVPR stroking differ with respect to dashing
            // pattern.
            // Convert a dashing (or other path effect) to either a stroke or a fill.
            if (style.applyPathEffectToPath(tmpPath.init(), &stroke, *skPath, SK_Scalar1)) {
                skPath = tmpPath.get();
            }
        } else {
            stroke = style.strokeRec();
        }

        bool didInit = false;
        if (stroke.needToApply() && stroke.getCap() != SkPaint::kButt_Cap) {
            // Skia stroking and NVPR stroking differ with respect to stroking
            // end caps of empty subpaths.
            // Convert stroke to fill if path contains empty subpaths.
            didInit = InitPathObjectPathDataCheckingDegenerates(gpu, fPathID, *skPath);
            if (!didInit) {
                if (!tmpPath.isValid()) {
                    tmpPath.init();
                }
                SkAssertResult(stroke.applyToPath(tmpPath.get(), *skPath));
                skPath = tmpPath.get();
                stroke.setFillStyle();
            }
        }

        if (!didInit) {
            InitPathObjectPathData(gpu, fPathID, *skPath);
        }

        fShouldStroke = stroke.needToApply();
        fShouldFill = stroke.isFillStyle() ||
                stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style;

        fFillType = convert_skpath_filltype(skPath->getFillType());
        fBounds = skPath->getBounds();
        SkScalar radius = stroke.getInflationRadius();
        fBounds.outset(radius, radius);
        if (fShouldStroke) {
            InitPathObjectStroke(gpu, fPathID, stroke);
        }
    }

    this->registerWithCache(SkBudgeted::kYes);
}

void GrGLPath::onRelease() {
    TRACE_EVENT0("skia.gpu", TRACE_FUNC);

    if (0 != fPathID) {
        static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fPathID, 1);
        fPathID = 0;
    }

    INHERITED::onRelease();
}

void GrGLPath::onAbandon() {
    fPathID = 0;

    INHERITED::onAbandon();
}
