180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrGLPath.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrGpuGL.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GPUGL static_cast<GrGpuGL*>(this->getGpu())
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GL_CALL_RET(R, X) GR_GL_CALL_RET(GPUGL->glInterface(), R, X)
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace {
180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline GrGLubyte verb_to_gl_path_cmd(SkPath::Verb verb) {
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const GrGLubyte gTable[] = {
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_MOVE_TO,
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_LINE_TO,
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_QUADRATIC_CURVE_TO,
2358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        0xFF, // conic
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_CUBIC_CURVE_TO,
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GR_GL_CLOSE_PATH,
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
3058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    GR_STATIC_ASSERT(4 == SkPath::kCubic_Verb);
3158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    GR_STATIC_ASSERT(5 == SkPath::kClose_Verb);
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkASSERT(verb >= 0 && (size_t)verb < GR_ARRAY_COUNT(gTable));
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return gTable[verb];
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
37d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#ifdef SK_DEBUG
380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline int num_pts(SkPath::Verb verb) {
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static const int gTable[] = {
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        1, // move
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        1, // line
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        2, // quad
4358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        2, // conic
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        3, // cubic
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        0, // close
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GR_STATIC_ASSERT(0 == SkPath::kMove_Verb);
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GR_STATIC_ASSERT(1 == SkPath::kLine_Verb);
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb);
5058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    GR_STATIC_ASSERT(4 == SkPath::kCubic_Verb);
5158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    GR_STATIC_ASSERT(5 == SkPath::kClose_Verb);
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkASSERT(verb >= 0 && (size_t)verb < GR_ARRAY_COUNT(gTable));
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return gTable[verb];
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
56d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger#endif
570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline GrGLenum join_to_gl_join(SkPaint::Join join) {
590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static GrGLenum gSkJoinsToGrGLJoins[] = {
600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GR_GL_MITER_REVERT,
610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GR_GL_ROUND,
620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GR_GL_BEVEL
630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    };
640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return gSkJoinsToGrGLJoins[join];
650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GR_STATIC_ASSERT(0 == SkPaint::kMiter_Join);
660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GR_STATIC_ASSERT(1 == SkPaint::kRound_Join);
670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GR_STATIC_ASSERT(2 == SkPaint::kBevel_Join);
680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GR_STATIC_ASSERT(GR_ARRAY_COUNT(gSkJoinsToGrGLJoins) == SkPaint::kJoinCount);
690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerinline GrGLenum cap_to_gl_cap(SkPaint::Cap cap) {
720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static GrGLenum gSkCapsToGrGLCaps[] = {
730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GR_GL_FLAT,
740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GR_GL_ROUND,
750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GR_GL_SQUARE
760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    };
770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return gSkCapsToGrGLCaps[cap];
780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GR_STATIC_ASSERT(0 == SkPaint::kButt_Cap);
790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GR_STATIC_ASSERT(1 == SkPaint::kRound_Cap);
800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GR_STATIC_ASSERT(2 == SkPaint::kSquare_Cap);
810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    GR_STATIC_ASSERT(GR_ARRAY_COUNT(gSkCapsToGrGLCaps) == SkPaint::kCapCount);
820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
86d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenbergerstatic const bool kIsWrapped = false; // The constructor creates the GL path object.
87d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
880a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerGrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke)
890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    : INHERITED(gpu, kIsWrapped, path, stroke) {
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SK_SCALAR_IS_FLOAT
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrCrash("Assumes scalar is float.");
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
93e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger    SkASSERT(!path.isEmpty());
94e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger
95e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger    GL_CALL_RET(fPathID, GenPaths(1));
96e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger
97e27eefc4844477cee5d32f51ab45ff62020cdb36Derek Sollenberger    SkSTArray<16, GrGLubyte, true> pathCommands;
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSTArray<16, SkPoint, true> pathPoints;
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int verbCnt = fSkPath.countVerbs();
1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int pointCnt = fSkPath.countPoints();
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pathCommands.resize_back(verbCnt);
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    pathPoints.resize_back(pointCnt);
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // TODO: Direct access to path points since we could pass them on directly.
1060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fSkPath.getPoints(&pathPoints[0], pointCnt);
1070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    fSkPath.getVerbs(&pathCommands[0], verbCnt);
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkDEBUGCODE(int numPts = 0);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < verbCnt; ++i) {
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]);
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        pathCommands[i] = verb_to_gl_path_cmd(v);
1130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDEBUGCODE(numPts += num_pts(v));
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
1150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkASSERT(pathPoints.count() == numPts);
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GL_CALL(PathCommands(fPathID,
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                         verbCnt, &pathCommands[0],
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                         2 * pointCnt, GR_GL_FLOAT, &pathPoints[0]));
1200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (stroke.needToApply()) {
1220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GL_CALL(PathParameterf(fPathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(stroke.getWidth())));
1230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GL_CALL(PathParameterf(fPathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(stroke.getMiter())));
1240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GrGLenum join = join_to_gl_join(stroke.getJoin());
1250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GL_CALL(PathParameteri(fPathID, GR_GL_PATH_JOIN_STYLE, join));
1260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GrGLenum cap = cap_to_gl_cap(stroke.getCap());
1270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GL_CALL(PathParameteri(fPathID, GR_GL_PATH_INITIAL_END_CAP, cap));
1280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        GL_CALL(PathParameteri(fPathID, GR_GL_PATH_TERMINAL_END_CAP, cap));
1290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        // FIXME: try to account for stroking, without rasterizing the stroke.
1310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fBounds.outset(SkScalarToFloat(stroke.getWidth()), SkScalarToFloat(stroke.getWidth()));
1320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrGLPath::~GrGLPath() {
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->release();
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrGLPath::onRelease() {
140d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (0 != fPathID && !this->isWrapped()) {
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GL_CALL(DeletePaths(fPathID, 1));
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPathID = 0;
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    INHERITED::onRelease();
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrGLPath::onAbandon() {
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPathID = 0;
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    INHERITED::onAbandon();
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
153