181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org/*
281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org * Copyright 2013 Google Inc.
381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org *
481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org * found in the LICENSE file.
681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org */
781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrOvalRenderer.h"
981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
1090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org#include "GrEffect.h"
1190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org#include "gl/GrGLEffect.h"
1290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org#include "gl/GrGLSL.h"
13261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org#include "gl/GrGLVertexEffect.h"
1490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org#include "GrTBackendEffectFactory.h"
1581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
1681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrDrawState.h"
1781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrDrawTarget.h"
18f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org#include "GrGpu.h"
19f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
20f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org#include "SkRRect.h"
2181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "SkStrokeRec.h"
220a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org#include "SkTLazy.h"
2381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
24234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org#include "effects/GrVertexEffect.h"
250a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org#include "effects/GrRRectEffect.h"
26234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org
2781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgnamespace {
2881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
2981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgstruct CircleVertex {
30972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fPos;
31972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fOffset;
3281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar fOuterRadius;
3381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar fInnerRadius;
3481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org};
3581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
3681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgstruct EllipseVertex {
37972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fPos;
38972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fOffset;
39972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fOuterRadii;
40972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fInnerRadii;
41f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org};
42f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
435242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgstruct DIEllipseVertex {
44972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fPos;
45972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fOuterOffset;
46972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint  fInnerOffset;
475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org};
485242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orginline bool circle_stays_circle(const SkMatrix& m) {
5081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    return m.isSimilarity();
5181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
5281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
5381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
5481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
5590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
5690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
5790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/**
5890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * The output of this effect is a modulation of the input color and coverage for a circle,
590a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org * specified as offset_x, offset_y (both from center point), outer radius and inner radius.
6090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org */
6190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
62234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.orgclass CircleEdgeEffect : public GrVertexEffect {
6390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgpublic:
6490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    static GrEffectRef* Create(bool stroke) {
65d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com        GR_CREATE_STATIC_EFFECT(gCircleStrokeEdge, CircleEdgeEffect, (true));
66d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com        GR_CREATE_STATIC_EFFECT(gCircleFillEdge, CircleEdgeEffect, (false));
6790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
6890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        if (stroke) {
69d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com            gCircleStrokeEdge->ref();
70d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com            return gCircleStrokeEdge;
7190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        } else {
72d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com            gCircleFillEdge->ref();
73d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com            return gCircleFillEdge;
7490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        }
7590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
7690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
77041e2dbc0614e3341e1349fd0e962744a45b6194skia.committer@gmail.com    virtual void getConstantColorComponents(GrColor* color,
7890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                                            uint32_t* validFlags) const SK_OVERRIDE {
7990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        *validFlags = 0;
8090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
8190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
8290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
8390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance();
8490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
8590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
8690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    virtual ~CircleEdgeEffect() {}
8790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
8890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    static const char* Name() { return "CircleEdge"; }
8990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
9090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    inline bool isStroked() const { return fStroke; }
9190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
92261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    class GLEffect : public GrGLVertexEffect {
9390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    public:
9490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
9590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        : INHERITED (factory) {}
9690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
97261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        virtual void emitCode(GrGLFullShaderBuilder* builder,
9890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              const GrDrawEffect& drawEffect,
9990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              EffectKey key,
10090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              const char* outputColor,
10190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              const char* inputColor,
10277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com                              const TransformedCoordsArray&,
10390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              const TextureSamplerArray& samplers) SK_OVERRIDE {
10490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleEdgeEffect>();
10590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            const char *vsName, *fsName;
106261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName);
10790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
10890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            const SkString* attrName =
109261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
110261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
11190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
1120a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org            builder->fsCodeAppendf("\tfloat d = length(%s.xy);\n", fsName);
11390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName);
11490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            if (circleEffect.isStroked()) {
11590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName);
11690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n");
11790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            }
1180a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org
119824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
120a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                                   (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
12190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        }
12290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
12390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
12490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleEdgeEffect>();
12590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
12690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            return circleEffect.isStroked() ? 0x1 : 0x0;
12790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        }
12890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
12990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
13090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
13190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    private:
132261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        typedef GrGLVertexEffect INHERITED;
13390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    };
13490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
13590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
13690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgprivate:
137234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org    CircleEdgeEffect(bool stroke) : GrVertexEffect() {
13890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        this->addVertexAttrib(kVec4f_GrSLType);
13990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        fStroke = stroke;
14090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
14190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
14290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
14390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other);
14490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        return cee.fStroke == fStroke;
14590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
14690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
14790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    bool fStroke;
14890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
14990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    GR_DECLARE_EFFECT_TEST;
15090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
151234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org    typedef GrVertexEffect INHERITED;
15290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org};
15390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
15490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgGR_DEFINE_EFFECT_TEST(CircleEdgeEffect);
15590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
156e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgGrEffectRef* CircleEdgeEffect::TestCreate(SkRandom* random,
15790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                                          GrContext* context,
15890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                                          const GrDrawTargetCaps&,
15990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                                          GrTexture* textures[]) {
16090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    return CircleEdgeEffect::Create(random->nextBool());
16190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org}
16290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
16390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
16490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
16590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/**
16690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * The output of this effect is a modulation of the input color and coverage for an axis-aligned
1678be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com * ellipse, specified as a 2D offset from center, and the reciprocals of the outer and inner radii,
1688be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com * in both x and y directions.
1698be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com *
1706bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0.
17190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org */
17290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
173234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.orgclass EllipseEdgeEffect : public GrVertexEffect {
17490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgpublic:
17590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    static GrEffectRef* Create(bool stroke) {
176d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com        GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, EllipseEdgeEffect, (true));
177d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com        GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, EllipseEdgeEffect, (false));
17890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
17990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        if (stroke) {
180d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com            gEllipseStrokeEdge->ref();
181d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com            return gEllipseStrokeEdge;
18290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        } else {
183d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com            gEllipseFillEdge->ref();
184d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com            return gEllipseFillEdge;
18590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        }
18690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
18790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
188041e2dbc0614e3341e1349fd0e962744a45b6194skia.committer@gmail.com    virtual void getConstantColorComponents(GrColor* color,
18990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                                            uint32_t* validFlags) const SK_OVERRIDE {
19090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        *validFlags = 0;
19190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
19290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
19390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
19490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance();
19590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
19690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
19790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    virtual ~EllipseEdgeEffect() {}
19890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
19990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    static const char* Name() { return "EllipseEdge"; }
20090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
20190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    inline bool isStroked() const { return fStroke; }
20290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
203261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    class GLEffect : public GrGLVertexEffect {
20490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    public:
20590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
20690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        : INHERITED (factory) {}
20790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
208261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        virtual void emitCode(GrGLFullShaderBuilder* builder,
20990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              const GrDrawEffect& drawEffect,
21090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              EffectKey key,
21190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              const char* outputColor,
21290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              const char* inputColor,
21377af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com                              const TransformedCoordsArray&,
21490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                              const TextureSamplerArray& samplers) SK_OVERRIDE {
21590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<EllipseEdgeEffect>();
21690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
2176bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            const char *vsOffsetName, *fsOffsetName;
2180a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org            const char *vsRadiiName, *fsRadiiName;
21990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
220261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->addVarying(kVec2f_GrSLType, "EllipseOffsets", &vsOffsetName, &fsOffsetName);
22190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            const SkString* attr0Name =
222261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
223261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName, attr0Name->c_str());
22490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
225261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->addVarying(kVec4f_GrSLType, "EllipseRadii", &vsRadiiName, &fsRadiiName);
22690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            const SkString* attr1Name =
227261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
228261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->vsCodeAppendf("\t%s = %s;\n", vsRadiiName, attr1Name->c_str());
22990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
2308be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com            // for outer curve
2316bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            builder->fsCodeAppendf("\tvec2 scaledOffset = %s*%s.xy;\n", fsOffsetName, fsRadiiName);
2326bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            builder->fsCodeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
2336bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            builder->fsCodeAppendf("\tvec2 grad = 2.0*scaledOffset*%s.xy;\n", fsRadiiName);
234d1b5b14747212e372f804ae9d732b1a923dbf66bjvanverth@google.com            builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n");
2351b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org            // avoid calling inversesqrt on zero.
2361b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org            builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
237d1b5b14747212e372f804ae9d732b1a923dbf66bjvanverth@google.com            builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
2386bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
239f58d8540a42e5138e7cdb1dd1e0b4de0fa3c4a10jvanverth@google.com
2406bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            // for inner curve
24174d50a4d125c551bc92235d0ba621bee216f3650commit-bot@chromium.org            if (ellipseEffect.isStroked()) {
2426bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                builder->fsCodeAppendf("\tscaledOffset = %s*%s.zw;\n", fsOffsetName, fsRadiiName);
2436bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                builder->fsCodeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
2446bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                builder->fsCodeAppendf("\tgrad = 2.0*scaledOffset*%s.zw;\n", fsRadiiName);
2456bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                builder->fsCodeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
2466bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
24790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            }
24890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
249824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
250a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                                   (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
25190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        }
25290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
25390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
25490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<EllipseEdgeEffect>();
25590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
25690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org            return ellipseEffect.isStroked() ? 0x1 : 0x0;
25790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        }
25890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
25990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
26090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        }
26190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
26290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    private:
263261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        typedef GrGLVertexEffect INHERITED;
26490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    };
26590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
26690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgprivate:
267234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org    EllipseEdgeEffect(bool stroke) : GrVertexEffect() {
26890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        this->addVertexAttrib(kVec2f_GrSLType);
26990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        this->addVertexAttrib(kVec4f_GrSLType);
27090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        fStroke = stroke;
27190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
27290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
27390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
27490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other);
27590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org        return eee.fStroke == fStroke;
27690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    }
27790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
27890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    bool fStroke;
27990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
28090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    GR_DECLARE_EFFECT_TEST;
28190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
282234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org    typedef GrVertexEffect INHERITED;
28390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org};
28490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
28590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgGR_DEFINE_EFFECT_TEST(EllipseEdgeEffect);
28690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
287e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgGrEffectRef* EllipseEdgeEffect::TestCreate(SkRandom* random,
28890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                                           GrContext* context,
28990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                                           const GrDrawTargetCaps&,
29090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org                                           GrTexture* textures[]) {
29190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org    return EllipseEdgeEffect::Create(random->nextBool());
29290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org}
29390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
29490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
29590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org
2965242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org/**
2976fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com * The output of this effect is a modulation of the input color and coverage for an ellipse,
2985242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * specified as a 2D offset from center for both the outer and inner paths (if stroked). The
2995242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge corrected by
3005242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * using differentials.
3015242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org *
3025242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * The result is device-independent and can be used with any affine matrix.
3035242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org */
3045242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
305234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.orgclass DIEllipseEdgeEffect : public GrVertexEffect {
3065242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgpublic:
3075242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    enum Mode { kStroke = 0, kHairline, kFill };
3085242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3095242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    static GrEffectRef* Create(Mode mode) {
3105242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        GR_CREATE_STATIC_EFFECT(gEllipseStrokeEdge, DIEllipseEdgeEffect, (kStroke));
3115242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        GR_CREATE_STATIC_EFFECT(gEllipseHairlineEdge, DIEllipseEdgeEffect, (kHairline));
3125242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        GR_CREATE_STATIC_EFFECT(gEllipseFillEdge, DIEllipseEdgeEffect, (kFill));
3136fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com
3145242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        if (kStroke == mode) {
3155242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            gEllipseStrokeEdge->ref();
3165242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            return gEllipseStrokeEdge;
3175242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        } else if (kHairline == mode) {
3185242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            gEllipseHairlineEdge->ref();
3195242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            return gEllipseHairlineEdge;
3205242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        } else {
3215242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            gEllipseFillEdge->ref();
3225242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            return gEllipseFillEdge;
3235242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        }
3245242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    }
3255242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3265242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    virtual void getConstantColorComponents(GrColor* color,
3275242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                            uint32_t* validFlags) const SK_OVERRIDE {
3285242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        *validFlags = 0;
3295242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    }
3305242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3315242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
3325242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        return GrTBackendEffectFactory<DIEllipseEdgeEffect>::getInstance();
3335242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    }
3345242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3355242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    virtual ~DIEllipseEdgeEffect() {}
3365242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3375242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    static const char* Name() { return "DIEllipseEdge"; }
3385242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3395242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    inline Mode getMode() const { return fMode; }
3405242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
341261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org    class GLEffect : public GrGLVertexEffect {
3425242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    public:
3435242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
3445242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        : INHERITED (factory) {}
3455242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
346261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        virtual void emitCode(GrGLFullShaderBuilder* builder,
3475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                              const GrDrawEffect& drawEffect,
3485242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                              EffectKey key,
3495242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                              const char* outputColor,
3505242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                              const char* inputColor,
35177af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com                              const TransformedCoordsArray&,
3525242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                              const TextureSamplerArray& samplers) SK_OVERRIDE {
3535242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIEllipseEdgeEffect>();
3545242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3555242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            SkAssertResult(builder->enableFeature(
3565242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                              GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
3575242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
35896a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org            const char *vsOffsetName0, *fsOffsetName0;
359261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->addVarying(kVec2f_GrSLType, "EllipseOffsets0",
36096a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                                      &vsOffsetName0, &fsOffsetName0);
3615242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            const SkString* attr0Name =
362261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
363261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName0, attr0Name->c_str());
36496a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org            const char *vsOffsetName1, *fsOffsetName1;
365261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->addVarying(kVec2f_GrSLType, "EllipseOffsets1",
36696a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                                      &vsOffsetName1, &fsOffsetName1);
36796a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org            const SkString* attr1Name =
368261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org                builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]);
369261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org            builder->vsCodeAppendf("\t%s = %s;\n", vsOffsetName1, attr1Name->c_str());
3705242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3715242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            // for outer curve
37296a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org            builder->fsCodeAppendf("\tvec2 scaledOffset = %s.xy;\n", fsOffsetName0);
3735242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            builder->fsCodeAppend("\tfloat test = dot(scaledOffset, scaledOffset) - 1.0;\n");
37496a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org            builder->fsCodeAppendf("\tvec2 duvdx = dFdx(%s);\n", fsOffsetName0);
37596a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org            builder->fsCodeAppendf("\tvec2 duvdy = dFdy(%s);\n", fsOffsetName0);
3765242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            builder->fsCodeAppendf("\tvec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
3775242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                   "\t                 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
37896a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                                   fsOffsetName0, fsOffsetName0, fsOffsetName0, fsOffsetName0);
3795242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3805242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            builder->fsCodeAppend("\tfloat grad_dot = dot(grad, grad);\n");
3811b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org            // avoid calling inversesqrt on zero.
3821b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org            builder->fsCodeAppend("\tgrad_dot = max(grad_dot, 1.0e-4);\n");
3835242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            builder->fsCodeAppend("\tfloat invlen = inversesqrt(grad_dot);\n");
3845242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            if (kHairline == ellipseEffect.getMode()) {
3855242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                // can probably do this with one step
3865242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                builder->fsCodeAppend("\tfloat edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);\n");
3875242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                builder->fsCodeAppend("\tedgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);\n");
3885242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            } else {
3895242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                builder->fsCodeAppend("\tfloat edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);\n");
3905242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            }
3915242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
3925242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            // for inner curve
3935242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            if (kStroke == ellipseEffect.getMode()) {
39496a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                builder->fsCodeAppendf("\tscaledOffset = %s.xy;\n", fsOffsetName1);
3955242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                builder->fsCodeAppend("\ttest = dot(scaledOffset, scaledOffset) - 1.0;\n");
39696a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                builder->fsCodeAppendf("\tduvdx = dFdx(%s);\n", fsOffsetName1);
39796a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                builder->fsCodeAppendf("\tduvdy = dFdy(%s);\n", fsOffsetName1);
39896a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                builder->fsCodeAppendf("\tgrad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y,\n"
39996a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                                       "\t            2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);\n",
40096a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org                                       fsOffsetName1, fsOffsetName1, fsOffsetName1, fsOffsetName1);
4015242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                builder->fsCodeAppend("\tinvlen = inversesqrt(dot(grad, grad));\n");
4025242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                builder->fsCodeAppend("\tedgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);\n");
4035242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            }
4045242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
405824c346b6e0e114063c1a8ad4ba7c3a669ee2cffcommit-bot@chromium.org            builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
406a34995e18b1f0a7d8c9f23451718bb30ff0105b0commit-bot@chromium.org                                   (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
4075242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        }
4085242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4095242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
4105242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            const DIEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<DIEllipseEdgeEffect>();
4116fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com
4125242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            return ellipseEffect.getMode();
4135242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        }
4145242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4155242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {
4165242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        }
4175242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4185242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    private:
419261dc569b6a53729bea6e4e7a0cf2afa980eb82dcommit-bot@chromium.org        typedef GrGLVertexEffect INHERITED;
4205242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    };
4215242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4225242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgprivate:
423234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org    DIEllipseEdgeEffect(Mode mode) : GrVertexEffect() {
42496a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org        this->addVertexAttrib(kVec2f_GrSLType);
42596a7a9623f7b00bacf502adb99d485f2b376d328commit-bot@chromium.org        this->addVertexAttrib(kVec2f_GrSLType);
4265242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        fMode = mode;
4275242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    }
4285242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4295242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
4305242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        const DIEllipseEdgeEffect& eee = CastEffect<DIEllipseEdgeEffect>(other);
4315242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        return eee.fMode == fMode;
4325242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    }
4335242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4345242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    Mode fMode;
4355242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4365242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    GR_DECLARE_EFFECT_TEST;
4375242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
438234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org    typedef GrVertexEffect INHERITED;
4395242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org};
4405242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4415242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgGR_DEFINE_EFFECT_TEST(DIEllipseEdgeEffect);
4425242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
443e0e7cfe44bb9d66d76120a79e5275c294bacaa22commit-bot@chromium.orgGrEffectRef* DIEllipseEdgeEffect::TestCreate(SkRandom* random,
4445242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                             GrContext* context,
4455242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                             const GrDrawTargetCaps&,
4465242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                             GrTexture* textures[]) {
4475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2)));
4485242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org}
4495242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
4505242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
4515242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
452ef284a84f503adfd08ee52b5aee142c548698ea4commit-bot@chromium.orgvoid GrOvalRenderer::reset() {
453a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeSetNull(fRRectIndexBuffer);
454ef284a84f503adfd08ee52b5aee142c548698ea4commit-bot@chromium.org}
455ef284a84f503adfd08ee52b5aee142c548698ea4commit-bot@chromium.org
45637d883d9d3c5945e9d121830bdcd1935160fd53bcommit-bot@chromium.orgbool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bool useAA,
457fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                              const SkRect& oval, const SkStrokeRec& stroke)
45881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org{
459e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    bool useCoverageAA = useAA &&
460e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        !target->getDrawState().getRenderTarget()->isMultisampled() &&
461e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        !target->shouldDisableCoverageAAForBlend();
462e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org
463e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    if (!useCoverageAA) {
46481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return false;
46581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
46681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
46781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    const SkMatrix& vm = context->getMatrix();
46881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
4697e32851d5473d14db5c396f5877e3dfcb7b19f6dskia.committer@gmail.com    // we can draw circles
4707e32851d5473d14db5c396f5877e3dfcb7b19f6dskia.committer@gmail.com    if (SkScalarNearlyEqual(oval.width(), oval.height())
47181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        && circle_stays_circle(vm)) {
472e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        this->drawCircle(target, useCoverageAA, oval, stroke);
4735242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    // if we have shader derivative support, render as device-independent
4745242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    } else if (target->caps()->shaderDerivativeSupport()) {
475e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        return this->drawDIEllipse(target, useCoverageAA, oval, stroke);
4765242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    // otherwise axis-aligned ellipses only
47781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    } else if (vm.rectStaysRect()) {
478e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        return this->drawEllipse(target, useCoverageAA, oval, stroke);
47981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    } else {
48081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return false;
48181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
48281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
48381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    return true;
48481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
48581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
486f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
487f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
488429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com// position + edge
489429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gCircleVertexAttribs[] = {
490429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
491972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    {kVec4f_GrVertexAttribType, sizeof(SkPoint), kEffect_GrVertexAttribBinding}
492429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com};
493429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
4947e32851d5473d14db5c396f5877e3dfcb7b19f6dskia.committer@gmail.comvoid GrOvalRenderer::drawCircle(GrDrawTarget* target,
495e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org                                bool useCoverageAA,
496fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                                const SkRect& circle,
49781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                                const SkStrokeRec& stroke)
49881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org{
49981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawState* drawState = target->drawState();
50081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
50181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    const SkMatrix& vm = drawState->getViewMatrix();
502972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY());
50381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    vm.mapPoints(&center, 1);
50481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width()));
50581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar strokeWidth = vm.mapRadius(stroke.getWidth());
50681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
507137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    GrDrawState::AutoViewMatrixRestore avmr;
508137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    if (!avmr.setIdentity(drawState)) {
50981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return;
51081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
51181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
512429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs));
513f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(sizeof(CircleVertex) == drawState->getVertexSize());
51481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
51581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
51681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (!geo.succeeded()) {
51781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        GrPrintf("Failed to get space for vertices!\n");
51881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return;
51981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
52081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
52181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
52281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
52381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkStrokeRec::Style style = stroke.getStyle();
5240a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
5250a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                        SkStrokeRec::kHairline_Style == style;
5260a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
5277e32851d5473d14db5c396f5877e3dfcb7b19f6dskia.committer@gmail.com
52881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar innerRadius = 0.0f;
52981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar outerRadius = radius;
53081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar halfWidth = 0;
5310a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (hasStroke) {
53281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        if (SkScalarNearlyZero(strokeWidth)) {
53381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            halfWidth = SK_ScalarHalf;
53481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        } else {
53581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            halfWidth = SkScalarHalf(strokeWidth);
53681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        }
53781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
53881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        outerRadius += halfWidth;
5390a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (isStrokeOnly) {
5406bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            innerRadius = radius - halfWidth;
54181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        }
54281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
54381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
5440a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    GrEffectRef* effect = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0);
545cefde6e5783bcce27369216e5e4ee5c7eed02e26commit-bot@chromium.org    static const int kCircleEdgeAttrIndex = 1;
546cefde6e5783bcce27369216e5e4ee5c7eed02e26commit-bot@chromium.org    drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref();
547cefde6e5783bcce27369216e5e4ee5c7eed02e26commit-bot@chromium.org
54858e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com    // The radii are outset for two reasons. First, it allows the shader to simply perform
54958e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com    // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the
55058e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com    // verts of the bounding box that is rendered and the outset ensures the box will cover all
55158e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com    // pixels partially covered by the circle.
55258e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com    outerRadius += SK_ScalarHalf;
55358e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com    innerRadius -= SK_ScalarHalf;
55458e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com
555bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    SkRect bounds = SkRect::MakeLTRB(
55658e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com        center.fX - outerRadius,
55758e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com        center.fY - outerRadius,
55858e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com        center.fX + outerRadius,
55958e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com        center.fY + outerRadius
560bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    );
561bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org
562bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    verts[0].fPos = SkPoint::Make(bounds.fLeft,  bounds.fTop);
5630a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[0].fOffset = SkPoint::Make(-outerRadius, -outerRadius);
5640a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[0].fOuterRadius = outerRadius;
5650a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[0].fInnerRadius = innerRadius;
5660a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org
567bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
5684674676438051c31a991fdab72efea3c7d0ca5a3skia.committer@gmail.com    verts[1].fOffset = SkPoint::Make(outerRadius, -outerRadius);
5690a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[1].fOuterRadius = outerRadius;
5700a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[1].fInnerRadius = innerRadius;
5710a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org
572bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    verts[2].fPos = SkPoint::Make(bounds.fLeft,  bounds.fBottom);
5730a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[2].fOffset = SkPoint::Make(-outerRadius, outerRadius);
5740a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[2].fOuterRadius = outerRadius;
5750a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[2].fInnerRadius = innerRadius;
5760a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org
577bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
5780a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[3].fOffset = SkPoint::Make(outerRadius, outerRadius);
5790a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[3].fOuterRadius = outerRadius;
5800a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[3].fInnerRadius = innerRadius;
581bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org
582bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
58381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
58481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
585f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
586f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
5875242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org// position + offset + 1/radii
588429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.comextern const GrVertexAttrib gEllipseVertexAttribs[] = {
589429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    {kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding},
590972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    {kVec2f_GrVertexAttribType, sizeof(SkPoint),   kEffect_GrVertexAttribBinding},
591972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    {kVec4f_GrVertexAttribType, 2*sizeof(SkPoint), kEffect_GrVertexAttribBinding}
592429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com};
593429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
5945242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org// position + offsets
5955242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgextern const GrVertexAttrib gDIEllipseVertexAttribs[] = {
5965242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    {kVec2f_GrVertexAttribType, 0,                 kPosition_GrVertexAttribBinding},
597972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    {kVec2f_GrVertexAttribType, sizeof(SkPoint),   kEffect_GrVertexAttribBinding},
598972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    {kVec2f_GrVertexAttribType, 2*sizeof(SkPoint), kEffect_GrVertexAttribBinding},
599429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com};
600429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
601c4f2ecaa475756bda48684b1158ec6b8bbdd1016jvanverth@google.combool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
602e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org                                 bool useCoverageAA,
603fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                                 const SkRect& ellipse,
60481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                                 const SkStrokeRec& stroke)
60581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org{
60681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawState* drawState = target->drawState();
60781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#ifdef SK_DEBUG
60881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    {
60981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // we should have checked for this previously
61081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect();
611e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        SkASSERT(useCoverageAA && isAxisAlignedEllipse);
61281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
61381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#endif
61481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
6150c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org    // do any matrix crunching before we reset the draw state for device coords
61681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    const SkMatrix& vm = drawState->getViewMatrix();
617972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
61881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    vm.mapPoints(&center, 1);
6190c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org    SkScalar ellipseXRadius = SkScalarHalf(ellipse.width());
6200c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org    SkScalar ellipseYRadius = SkScalarHalf(ellipse.height());
62164b682ca42c75667e49251d3ab04f192f92d0dd8skia.committer@gmail.com    SkScalar xRadius = SkScalarAbs(vm[SkMatrix::kMScaleX]*ellipseXRadius +
6220c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org                                   vm[SkMatrix::kMSkewY]*ellipseYRadius);
62364b682ca42c75667e49251d3ab04f192f92d0dd8skia.committer@gmail.com    SkScalar yRadius = SkScalarAbs(vm[SkMatrix::kMSkewX]*ellipseXRadius +
6240c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org                                   vm[SkMatrix::kMScaleY]*ellipseYRadius);
62581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
6260c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org    // do (potentially) anisotropic mapping of stroke
6270c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org    SkVector scaledStroke;
6280c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org    SkScalar strokeWidth = stroke.getWidth();
6290c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org    scaledStroke.fX = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMScaleX] + vm[SkMatrix::kMSkewY]));
6300c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org    scaledStroke.fY = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMSkewX] + vm[SkMatrix::kMScaleY]));
6310c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org
6326bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    SkStrokeRec::Style style = stroke.getStyle();
6330a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
6340a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                        SkStrokeRec::kHairline_Style == style;
6350a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
6366bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
6375242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar innerXRadius = 0;
6385242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar innerYRadius = 0;
6390a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (hasStroke) {
6406bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        if (SkScalarNearlyZero(scaledStroke.length())) {
6416bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf);
6426bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        } else {
6436bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            scaledStroke.scale(SK_ScalarHalf);
6446bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        }
6456bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
6466bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        // we only handle thick strokes for near-circular ellipses
6476bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        if (scaledStroke.length() > SK_ScalarHalf &&
6486bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) {
6496bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            return false;
6506bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        }
6516bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
6526bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        // we don't handle it if curvature of the stroke is less than curvature of the ellipse
6536bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY)*xRadius ||
6546bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX)*yRadius) {
6556bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            return false;
6566bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        }
6576bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
6586bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        // this is legit only if scale & translation (which should be the case at the moment)
6590a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (isStrokeOnly) {
6606bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            innerXRadius = xRadius - scaledStroke.fX;
6616bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            innerYRadius = yRadius - scaledStroke.fY;
6626bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        }
6636bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
6646bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        xRadius += scaledStroke.fX;
6656bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        yRadius += scaledStroke.fY;
6666bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    }
6676bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
668137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    GrDrawState::AutoViewMatrixRestore avmr;
669137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    if (!avmr.setIdentity(drawState)) {
670c4f2ecaa475756bda48684b1158ec6b8bbdd1016jvanverth@google.com        return false;
67181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
67281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
673429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs));
674f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(sizeof(EllipseVertex) == drawState->getVertexSize());
67581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
67681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
67781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (!geo.succeeded()) {
67881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        GrPrintf("Failed to get space for vertices!\n");
679c4f2ecaa475756bda48684b1158ec6b8bbdd1016jvanverth@google.com        return false;
68081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
68181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
68281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
68381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
6840a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    GrEffectRef* effect = EllipseEdgeEffect::Create(isStrokeOnly &&
685cefde6e5783bcce27369216e5e4ee5c7eed02e26commit-bot@chromium.org                                                    innerXRadius > 0 && innerYRadius > 0);
6866bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
68781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    static const int kEllipseCenterAttrIndex = 1;
6886cc8d4470df5fb2e8e4574bbfde1ebf82a3b7aefjvanverth@google.com    static const int kEllipseEdgeAttrIndex = 2;
6896cc8d4470df5fb2e8e4574bbfde1ebf82a3b7aefjvanverth@google.com    drawState->addCoverageEffect(effect, kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref();
69081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
6916bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    // Compute the reciprocals of the radii here to save time in the shader
6926bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    SkScalar xRadRecip = SkScalarInvert(xRadius);
6936bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    SkScalar yRadRecip = SkScalarInvert(yRadius);
6946bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
6956bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
69681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
6970a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    // We've extended the outer x radius out half a pixel to antialias.
6980a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    // This will also expand the rect so all the pixels will be captured.
6996bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    // TODO: Consider if we should use sqrt(2)/2 instead
7000a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    xRadius += SK_ScalarHalf;
7010a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    yRadius += SK_ScalarHalf;
7020a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org
7030a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    SkRect bounds = SkRect::MakeLTRB(
7040a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org        center.fX - xRadius,
7050a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org        center.fY - yRadius,
7060a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org        center.fX + xRadius,
7070a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org        center.fY + yRadius
7080a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    );
70981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
7100a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[0].fPos = SkPoint::Make(bounds.fLeft,  bounds.fTop);
7116bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[0].fOffset = SkPoint::Make(-xRadius, -yRadius);
7126bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[0].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
7136bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[0].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
71481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
7150a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
7166bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[1].fOffset = SkPoint::Make(xRadius, -yRadius);
7176bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[1].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
7186bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[1].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
7190a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org
7200a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[2].fPos = SkPoint::Make(bounds.fLeft,  bounds.fBottom);
7216bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[2].fOffset = SkPoint::Make(-xRadius, yRadius);
7226bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[2].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
7236bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
7240a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org
7250a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
7266bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[3].fOffset = SkPoint::Make(xRadius, yRadius);
7276bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
7286bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
7294674676438051c31a991fdab72efea3c7d0ca5a3skia.committer@gmail.com
7300a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
731c4f2ecaa475756bda48684b1158ec6b8bbdd1016jvanverth@google.com
732c4f2ecaa475756bda48684b1158ec6b8bbdd1016jvanverth@google.com    return true;
73381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
734f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
7355242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgbool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
736e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org                                   bool useCoverageAA,
7375242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                   const SkRect& ellipse,
7385242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                   const SkStrokeRec& stroke)
7395242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org{
7405242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    GrDrawState* drawState = target->drawState();
7415242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    const SkMatrix& vm = drawState->getViewMatrix();
7425242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
743972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
7445242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar xRadius = SkScalarHalf(ellipse.width());
7456fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com    SkScalar yRadius = SkScalarHalf(ellipse.height());
7466fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com
7475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkStrokeRec::Style style = stroke.getStyle();
7486fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com    DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ?
7495242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                    DIEllipseEdgeEffect::kStroke :
7506fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com                                    (SkStrokeRec::kHairline_Style == style) ?
7515242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                    DIEllipseEdgeEffect::kHairline : DIEllipseEdgeEffect::kFill;
7525242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
7535242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar innerXRadius = 0;
7545242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar innerYRadius = 0;
7555242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    if (SkStrokeRec::kFill_Style != style && SkStrokeRec::kHairline_Style != style) {
7565242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        SkScalar strokeWidth = stroke.getWidth();
7575242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
7585242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        if (SkScalarNearlyZero(strokeWidth)) {
7595242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            strokeWidth = SK_ScalarHalf;
7605242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        } else {
7615242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            strokeWidth *= SK_ScalarHalf;
7625242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        }
7635242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
7645242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        // we only handle thick strokes for near-circular ellipses
7655242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        if (strokeWidth > SK_ScalarHalf &&
7665242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) {
7675242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            return false;
7685242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        }
7695242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
7705242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        // we don't handle it if curvature of the stroke is less than curvature of the ellipse
7715242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius ||
7725242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) {
7735242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            return false;
7745242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        }
7755242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
7765242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        // set inner radius (if needed)
7775242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        if (SkStrokeRec::kStroke_Style == style) {
7785242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            innerXRadius = xRadius - strokeWidth;
7795242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org            innerYRadius = yRadius - strokeWidth;
7805242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        }
7815242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
7825242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        xRadius += strokeWidth;
7835242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        yRadius += strokeWidth;
7845242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    }
7855242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    if (DIEllipseEdgeEffect::kStroke == mode) {
7865242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kStroke :
7875242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                                        DIEllipseEdgeEffect::kFill;
7885242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    }
7895242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius);
7905242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius);
7915242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
7925242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllipseVertexAttribs));
7935242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkASSERT(sizeof(DIEllipseVertex) == drawState->getVertexSize());
7945242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
7955242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
7965242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    if (!geo.succeeded()) {
7975242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        GrPrintf("Failed to get space for vertices!\n");
7985242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        return false;
7995242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    }
8005242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8015242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(geo.vertices());
8025242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8035242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    GrEffectRef* effect = DIEllipseEdgeEffect::Create(mode);
8045242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8055242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    static const int kEllipseOuterOffsetAttrIndex = 1;
8065242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    static const int kEllipseInnerOffsetAttrIndex = 2;
8075242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    drawState->addCoverageEffect(effect, kEllipseOuterOffsetAttrIndex,
8085242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org                                         kEllipseInnerOffsetAttrIndex)->unref();
8096fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com
8105242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    // This expands the outer rect so that after CTM we end up with a half-pixel border
8115242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar a = vm[SkMatrix::kMScaleX];
8125242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar b = vm[SkMatrix::kMSkewX];
8135242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar c = vm[SkMatrix::kMSkewY];
8145242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar d = vm[SkMatrix::kMScaleY];
8155242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c));
8165242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d));
8175242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    // This adjusts the "radius" to include the half-pixel border
8185242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar offsetDx = SkScalarDiv(geoDx, xRadius);
8195242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkScalar offsetDy = SkScalarDiv(geoDy, yRadius);
8205242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8215242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    SkRect bounds = SkRect::MakeLTRB(
8225242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        center.fX - xRadius - geoDx,
8235242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        center.fY - yRadius - geoDy,
8245242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        center.fX + xRadius + geoDx,
8255242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org        center.fY + yRadius + geoDy
8265242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    );
8275242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8285242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop);
8295242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy);
8305242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[0].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, -innerRatioY - offsetDy);
8315242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8325242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
8335242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[1].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy);
8345242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[1].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
8355242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8365242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[2].fPos = SkPoint::Make(bounds.fLeft,  bounds.fBottom);
8375242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[2].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, 1.0f + offsetDy);
8385242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[2].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, innerRatioY + offsetDy);
8395242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8405242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
8415242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy);
8425242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerRatioY + offsetDy);
8435242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8445242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
8455242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
8465242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org    return true;
8475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org}
8485242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org
849f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
850f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
851f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.orgstatic const uint16_t gRRectIndices[] = {
852f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    // corners
853f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    0, 1, 5, 0, 5, 4,
854f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    2, 3, 7, 2, 7, 6,
855f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    8, 9, 13, 8, 13, 12,
856f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    10, 11, 15, 10, 15, 14,
8572cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
858f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    // edges
859f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    1, 2, 6, 1, 6, 5,
860f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    4, 5, 9, 4, 9, 8,
861f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    6, 7, 11, 6, 11, 10,
862f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    9, 10, 14, 9, 14, 13,
8632cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
864f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    // center
865f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    // we place this at the end so that we can ignore these indices when rendering stroke-only
866f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    5, 6, 10, 5, 10, 9
867f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org};
868f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
869f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
870f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.orgGrIndexBuffer* GrOvalRenderer::rRectIndexBuffer(GrGpu* gpu) {
871f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    if (NULL == fRRectIndexBuffer) {
872f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        fRRectIndexBuffer =
873f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        gpu->createIndexBuffer(sizeof(gRRectIndices), false);
874f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        if (NULL != fRRectIndexBuffer) {
875515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
876f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bool updated =
877f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org#endif
878f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            fRRectIndexBuffer->updateData(gRRectIndices,
879f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org                                          sizeof(gRRectIndices));
880f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            GR_DEBUGASSERT(updated);
881f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        }
882f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    }
883f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    return fRRectIndexBuffer;
884f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org}
885f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
8860a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.orgbool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrContext* context, bool useAA,
8878af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon                                const SkRRect& origOuter, const SkRRect& origInner) {
8888af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    bool applyAA = useAA &&
8898af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon                   !target->getDrawState().getRenderTarget()->isMultisampled() &&
8908af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon                   !target->shouldDisableCoverageAAForBlend();
8910a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    GrDrawState::AutoRestoreEffects are;
8920a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (!origInner.isEmpty()) {
8930a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        SkTCopyOnFirstWrite<SkRRect> inner(origInner);
8940a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (!context->getMatrix().isIdentity()) {
8950a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            if (!origInner.transform(context->getMatrix(), inner.writable())) {
8960a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                return false;
8970a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            }
8980a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        }
8990a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        GrEffectEdgeType edgeType = applyAA ? kInverseFillAA_GrEffectEdgeType :
9000a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                                              kInverseFillBW_GrEffectEdgeType;
9010a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        GrEffectRef* effect = GrRRectEffect::Create(edgeType, *inner);
9020a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (NULL == effect) {
9030a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            return false;
9040a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        }
9050a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        are.set(target->drawState());
9060a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        target->drawState()->addCoverageEffect(effect)->unref();
9070a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    }
9080a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
9090a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle);
9108af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    if (this->drawRRect(target, context, useAA, origOuter, fillRec)) {
9118af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon        return true;
9128af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    }
9138af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon
9148af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    SkASSERT(!origOuter.isEmpty());
9158af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    SkTCopyOnFirstWrite<SkRRect> outer(origOuter);
9168af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    if (!context->getMatrix().isIdentity()) {
9178af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon        if (!origOuter.transform(context->getMatrix(), outer.writable())) {
9188af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon            return false;
9198af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon        }
9208af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    }
9218af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    GrEffectEdgeType edgeType = applyAA ? kFillAA_GrEffectEdgeType :
9228af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon                                          kFillBW_GrEffectEdgeType;
9238af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    GrEffectRef* effect = GrRRectEffect::Create(edgeType, *outer);
9248af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    if (NULL == effect) {
9258af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon        return false;
9268af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    }
9278af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    if (!are.isSet()) {
9288af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon        are.set(target->drawState());
9298af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    }
9308af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    GrDrawState::AutoViewMatrixRestore avmr;
9318af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    if (!avmr.setIdentity(target->drawState())) {
9328af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon        return false;
9338af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    }
9348af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    target->drawState()->addCoverageEffect(effect)->unref();
9358af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    SkRect bounds = outer->getBounds();
9368af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    if (applyAA) {
9378af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon        bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
9388af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    }
9398af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    target->drawRect(bounds, NULL, NULL, NULL);
9408af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon    return true;
9410a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org}
9420a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
9430a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.orgbool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool useAA,
9440a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                               const SkRRect& rrect, const SkStrokeRec& stroke) {
9450a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (rrect.isOval()) {
9460a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        return this->drawOval(target, context, useAA, rrect.getBounds(), stroke);
9470a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    }
9480a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
949e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    bool useCoverageAA = useAA &&
950e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        !target->getDrawState().getRenderTarget()->isMultisampled() &&
951e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        !target->shouldDisableCoverageAAForBlend();
952e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org
95337d883d9d3c5945e9d121830bdcd1935160fd53bcommit-bot@chromium.org    // only anti-aliased rrects for now
954e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    if (!useCoverageAA) {
95537d883d9d3c5945e9d121830bdcd1935160fd53bcommit-bot@chromium.org        return false;
95637d883d9d3c5945e9d121830bdcd1935160fd53bcommit-bot@chromium.org    }
95737d883d9d3c5945e9d121830bdcd1935160fd53bcommit-bot@chromium.org
958f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    const SkMatrix& vm = context->getMatrix();
9590a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
9600a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (!vm.rectStaysRect() || !rrect.isSimple()) {
9610a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        return false;
962f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    }
963f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
964f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    // do any matrix crunching before we reset the draw state for device coords
965f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    const SkRect& rrectBounds = rrect.getBounds();
966f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    SkRect bounds;
967f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    vm.mapRect(&bounds, rrectBounds);
968f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
969f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    SkVector radii = rrect.getSimpleRadii();
9702cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com    SkScalar xRadius = SkScalarAbs(vm[SkMatrix::kMScaleX]*radii.fX +
971f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org                                   vm[SkMatrix::kMSkewY]*radii.fY);
9722cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com    SkScalar yRadius = SkScalarAbs(vm[SkMatrix::kMSkewX]*radii.fX +
973f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org                                   vm[SkMatrix::kMScaleY]*radii.fY);
9746bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
975f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    SkStrokeRec::Style style = stroke.getStyle();
976f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
977f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    // do (potentially) anisotropic mapping of stroke
978f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    SkVector scaledStroke;
979f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    SkScalar strokeWidth = stroke.getWidth();
980f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
9810a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
9820a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                        SkStrokeRec::kHairline_Style == style;
9830a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
9840a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
9850a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (hasStroke) {
9860a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (SkStrokeRec::kHairline_Style == style) {
9870a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            scaledStroke.set(1, 1);
9880a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        } else {
9890a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            scaledStroke.fX = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMScaleX] +
9900a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                                                       vm[SkMatrix::kMSkewY]));
9910a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            scaledStroke.fY = SkScalarAbs(strokeWidth*(vm[SkMatrix::kMSkewX] +
9920a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                                                       vm[SkMatrix::kMScaleY]));
9930a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        }
9940a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
9950a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        // if half of strokewidth is greater than radius, we don't handle that right now
9960a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStroke.fY > yRadius) {
9970a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            return false;
9980a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        }
9990a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    }
10000a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
10010a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    // The way the effect interpolates the offset-to-ellipse/circle-center attribute only works on
10020a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner rect of the nine-
10030a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    // patch will have fractional coverage. This only matters when the interior is actually filled.
10040a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    // We could consider falling back to rect rendering here, since a tiny radius is
10050a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    // indistinguishable from a square corner.
10060a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) {
1007f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        return false;
1008f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    }
1009f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1010f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    // reset to device coordinates
1011f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    GrDrawState* drawState = target->drawState();
1012137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    GrDrawState::AutoViewMatrixRestore avmr;
1013137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    if (!avmr.setIdentity(drawState)) {
1014f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        return false;
1015f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    }
1016f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1017f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(context->getGpu());
1018f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    if (NULL == indexBuffer) {
1019f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        GrPrintf("Failed to create index buffer!\n");
1020f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        return false;
10212cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com    }
10222cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1023f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    // if the corners are circles, use the circle renderer
10240a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius) {
1025f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs));
1026f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(sizeof(CircleVertex) == drawState->getVertexSize());
10272cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1028f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
1029f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        if (!geo.succeeded()) {
1030f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            GrPrintf("Failed to get space for vertices!\n");
1031f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            return false;
1032f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        }
1033f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
10342cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1035f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar innerRadius = 0.0f;
1036f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar outerRadius = xRadius;
1037f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar halfWidth = 0;
10380a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (hasStroke) {
1039f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            if (SkScalarNearlyZero(scaledStroke.fX)) {
1040f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org                halfWidth = SK_ScalarHalf;
1041f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            } else {
1042f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org                halfWidth = SkScalarHalf(scaledStroke.fX);
1043f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            }
10442cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
10450a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            if (isStrokeOnly) {
10466bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                innerRadius = xRadius - halfWidth;
1047f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            }
1048f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            outerRadius += halfWidth;
1049f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.outset(halfWidth, halfWidth);
1050f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        }
10512cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
10520a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
1053cefde6e5783bcce27369216e5e4ee5c7eed02e26commit-bot@chromium.org
10540a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        GrEffectRef* effect = CircleEdgeEffect::Create(isStrokeOnly);
10556bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        static const int kCircleEdgeAttrIndex = 1;
1056eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        drawState->addCoverageEffect(effect, kCircleEdgeAttrIndex)->unref();
10578be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com
1058f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // The radii are outset for two reasons. First, it allows the shader to simply perform
1059f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // clamp(distance-to-center - radius, 0, 1). Second, the outer radius is used to compute the
1060f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // verts of the bounding box that is rendered and the outset ensures the box will cover all
1061f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // pixels partially covered by the circle.
1062f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        outerRadius += SK_ScalarHalf;
1063f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        innerRadius -= SK_ScalarHalf;
10642cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1065f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // Expand the rect so all the pixels will be captured.
1066f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
10672cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1068f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar yCoords[4] = {
1069f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.fTop,
1070f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.fTop + outerRadius,
1071f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.fBottom - outerRadius,
1072f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.fBottom
1073f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        };
1074f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar yOuterRadii[4] = {
1075f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            -outerRadius,
1076f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            0,
1077f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            0,
1078f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            outerRadius
1079f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        };
1080f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        for (int i = 0; i < 4; ++i) {
1081f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]);
1082f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOffset = SkPoint::Make(-outerRadius, yOuterRadii[i]);
1083f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOuterRadius = outerRadius;
1084f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fInnerRadius = innerRadius;
1085f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts++;
10862cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1087f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[i]);
1088f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOffset = SkPoint::Make(0, yOuterRadii[i]);
1089f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOuterRadius = outerRadius;
1090f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fInnerRadius = innerRadius;
1091f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts++;
10922cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1093f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords[i]);
1094f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOffset = SkPoint::Make(0, yOuterRadii[i]);
1095f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOuterRadius = outerRadius;
1096f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fInnerRadius = innerRadius;
1097f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts++;
10982cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1099f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]);
1100f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOffset = SkPoint::Make(outerRadius, yOuterRadii[i]);
1101f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOuterRadius = outerRadius;
1102f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fInnerRadius = innerRadius;
1103f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts++;
1104f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        }
11052cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1106f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // drop out the middle quad if we're stroked
11070a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
11080a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                                      SK_ARRAY_COUNT(gRRectIndices);
1109f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        target->setIndexSourceToBuffer(indexBuffer);
1110f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bounds);
11112cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
11126bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org    // otherwise we use the ellipse renderer
1113f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    } else {
1114f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs));
1115f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(sizeof(EllipseVertex) == drawState->getVertexSize());
1116f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1117f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar innerXRadius = 0.0f;
1118f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar innerYRadius = 0.0f;
11190a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        if (hasStroke) {
1120f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            if (SkScalarNearlyZero(scaledStroke.length())) {
1121f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org                scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf);
1122f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            } else {
11236bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                scaledStroke.scale(SK_ScalarHalf);
11246bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            }
11256bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
11266bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            // we only handle thick strokes for near-circular ellipses
11278be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com            if (scaledStroke.length() > SK_ScalarHalf &&
11286bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) {
11296bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                return false;
11306bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            }
11316bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
11326bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            // we don't handle it if curvature of the stroke is less than curvature of the ellipse
11336bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY)*xRadius ||
11346bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX)*yRadius) {
11356bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                return false;
1136f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            }
1137f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1138f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            // this is legit only if scale & translation (which should be the case at the moment)
11390a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org            if (isStrokeOnly) {
11406bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                innerXRadius = xRadius - scaledStroke.fX;
11416bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org                innerYRadius = yRadius - scaledStroke.fY;
1142f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            }
11436bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
1144f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            xRadius += scaledStroke.fX;
1145f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            yRadius += scaledStroke.fY;
1146f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.outset(scaledStroke.fX, scaledStroke.fY);
1147f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        }
1148f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
11490a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
1150cefde6e5783bcce27369216e5e4ee5c7eed02e26commit-bot@chromium.org
11516bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
11526bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        if (!geo.succeeded()) {
11536bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            GrPrintf("Failed to get space for vertices!\n");
11546bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            return false;
11556bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        }
11566bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
11576bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
11580a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        GrEffectRef* effect = EllipseEdgeEffect::Create(isStrokeOnly);
11596bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        static const int kEllipseOffsetAttrIndex = 1;
11606bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        static const int kEllipseRadiiAttrIndex = 2;
1161eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        drawState->addCoverageEffect(effect,
1162eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                                     kEllipseOffsetAttrIndex, kEllipseRadiiAttrIndex)->unref();
11636bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
11646bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        // Compute the reciprocals of the radii here to save time in the shader
11656bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        SkScalar xRadRecip = SkScalarInvert(xRadius);
11666bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        SkScalar yRadRecip = SkScalarInvert(yRadius);
11676bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        SkScalar xInnerRadRecip = SkScalarInvert(innerXRadius);
11686bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org        SkScalar yInnerRadRecip = SkScalarInvert(innerYRadius);
11696bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org
1170f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // Extend the radii out half a pixel to antialias.
1171f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar xOuterRadius = xRadius + SK_ScalarHalf;
1172f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar yOuterRadius = yRadius + SK_ScalarHalf;
1173f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1174f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // Expand the rect so all the pixels will be captured.
1175f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
1176f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1177f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar yCoords[4] = {
1178f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.fTop,
1179f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.fTop + yOuterRadius,
1180f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.fBottom - yOuterRadius,
1181f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            bounds.fBottom
1182f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        };
1183f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkScalar yOuterOffsets[4] = {
1184d1b5b14747212e372f804ae9d732b1a923dbf66bjvanverth@google.com            yOuterRadius,
1185f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            SK_ScalarNearlyZero, // we're using inversesqrt() in the shader, so can't be exactly 0
1186f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            SK_ScalarNearlyZero,
1187f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            yOuterRadius
1188f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        };
1189f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1190f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        for (int i = 0; i < 4; ++i) {
1191f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]);
1192d1b5b14747212e372f804ae9d732b1a923dbf66bjvanverth@google.com            verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]);
11936bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
11946bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
1195f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts++;
1196f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1197f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fPos = SkPoint::Make(bounds.fLeft + xOuterRadius, yCoords[i]);
1198f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i]);
11996bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
12006bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
1201f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts++;
1202f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1203f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fPos = SkPoint::Make(bounds.fRight - xOuterRadius, yCoords[i]);
1204f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i]);
12056bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
12066bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
1207f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts++;
1208f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1209f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]);
1210f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]);
12116bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
12126bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org            verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
1213f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org            verts++;
1214f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        }
12152cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1216f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        // drop out the middle quad if we're stroked
12170a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
12180a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                                      SK_ARRAY_COUNT(gRRectIndices);
1219f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        target->setIndexSourceToBuffer(indexBuffer);
1220f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bounds);
1221f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    }
12222cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com
1223f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    return true;
1224f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org}
1225