GrOvalOpFactory.cpp revision 81312830ef73420efdc4821feb7c2d6fd9152af8
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
1081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "effects/GrCircleEdgeEffect.h"
1181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "effects/GrEllipseEdgeEffect.h"
1281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
1381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrDrawState.h"
1481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrDrawTarget.h"
1581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "SkStrokeRec.h"
1681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
1781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgSK_DEFINE_INST_COUNT(GrOvalRenderer)
1881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
1981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgnamespace {
2081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
2181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgstruct CircleVertex {
2281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrPoint fPos;
2381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrPoint fCenter;
2481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar fOuterRadius;
2581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar fInnerRadius;
2681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org};
2781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
2881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgstruct EllipseVertex {
2981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrPoint fPos;
3081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrPoint fCenter;
3181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar fOuterXRadius;
3281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar fOuterXYRatio;
3381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar fInnerXRadius;
3481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar fInnerXYRatio;
3581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org};
3681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
3781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orginline bool circle_stays_circle(const SkMatrix& m) {
3881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    return m.isSimilarity();
3981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
4081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
4181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
4281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
4381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgbool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, const GrPaint& paint,
4481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                    const GrRect& oval, const SkStrokeRec& stroke)
4581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org{
4681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (!paint.isAntiAlias()) {
4781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return false;
4881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
4981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
5081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    const SkMatrix& vm = context->getMatrix();
5181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
5281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // we can draw circles
5381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (SkScalarNearlyEqual(oval.width(), oval.height())
5481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        && circle_stays_circle(vm)) {
5581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        drawCircle(target, paint, oval, stroke);
5681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
5781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // and axis-aligned ellipses only
5881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    } else if (vm.rectStaysRect()) {
5981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        drawEllipse(target, paint, oval, stroke);
6081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
6181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    } else {
6281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return false;
6381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
6481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
6581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    return true;
6681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
6781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
6881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgvoid GrOvalRenderer::drawCircle(GrDrawTarget* target,
6981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                                const GrPaint& paint,
7081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                                const GrRect& circle,
7181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                                const SkStrokeRec& stroke)
7281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org{
7381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawState* drawState = target->drawState();
7481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
7581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    const SkMatrix& vm = drawState->getViewMatrix();
7681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrPoint center = GrPoint::Make(circle.centerX(), circle.centerY());
7781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    vm.mapPoints(&center, 1);
7881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar radius = vm.mapRadius(SkScalarHalf(circle.width()));
7981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar strokeWidth = vm.mapRadius(stroke.getWidth());
8081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
8181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawState::AutoDeviceCoordDraw adcd(drawState);
8281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (!adcd.succeeded()) {
8381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return;
8481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
8581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
8681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // position + edge
8781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    static const GrVertexAttrib kVertexAttribs[] = {
8881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        {kVec2f_GrVertexAttribType, 0},
8981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        {kVec4f_GrVertexAttribType, sizeof(GrPoint)}
9081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    };
9181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
9281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
9381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrAssert(sizeof(CircleVertex) == drawState->getVertexSize());
9481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
9581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
9681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (!geo.succeeded()) {
9781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        GrPrintf("Failed to get space for vertices!\n");
9881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return;
9981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
10081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
10181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    CircleVertex* verts = reinterpret_cast<CircleVertex*>(geo.vertices());
10281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
10381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkStrokeRec::Style style = stroke.getStyle();
10481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style);
10581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    enum {
10681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // the edge effects share this stage with glyph rendering
10781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // (kGlyphMaskStage in GrTextContext) && SW path rendering
10881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // (kPathMaskStage in GrSWMaskHelper)
10981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        kEdgeEffectStage = GrPaint::kTotalStages,
11081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    };
11181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings);
11281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
11381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrEffectRef* effect = GrCircleEdgeEffect::Create(isStroked);
11481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    static const int kCircleEdgeAttrIndex = 1;
11581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref();
11681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
11781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar innerRadius = 0.0f;
11881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar outerRadius = radius;
11981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar halfWidth = 0;
12081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (style != SkStrokeRec::kFill_Style) {
12181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        if (SkScalarNearlyZero(strokeWidth)) {
12281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            halfWidth = SK_ScalarHalf;
12381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        } else {
12481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            halfWidth = SkScalarHalf(strokeWidth);
12581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        }
12681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
12781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        outerRadius += halfWidth;
12881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        if (isStroked) {
12981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            innerRadius = SkMaxScalar(0, radius - halfWidth);
13081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        }
13181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
13281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
13381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    for (int i = 0; i < 4; ++i) {
13481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        verts[i].fCenter = center;
13581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        verts[i].fOuterRadius = outerRadius + 0.5f;
13681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        verts[i].fInnerRadius = innerRadius - 0.5f;
13781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
13881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
13981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar L = -outerRadius;
14081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar R = +outerRadius;
14181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar T = -outerRadius;
14281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar B = +outerRadius;
14381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
14481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // We've extended the outer radius out half a pixel to antialias.
14581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // Expand the drawn rect here so all the pixels will be captured.
14681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    L += center.fX - SK_ScalarHalf;
14781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    R += center.fX + SK_ScalarHalf;
14881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    T += center.fY - SK_ScalarHalf;
14981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    B += center.fY + SK_ScalarHalf;
15081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
15181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    verts[0].fPos = SkPoint::Make(L, T);
15281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    verts[1].fPos = SkPoint::Make(R, T);
15381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    verts[2].fPos = SkPoint::Make(L, B);
15481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    verts[3].fPos = SkPoint::Make(R, B);
15581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
15681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4);
15781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
15881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
15981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgvoid GrOvalRenderer::drawEllipse(GrDrawTarget* target,
16081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                                 const GrPaint& paint,
16181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                                 const GrRect& ellipse,
16281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                                 const SkStrokeRec& stroke)
16381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org{
16481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawState* drawState = target->drawState();
16581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#ifdef SK_DEBUG
16681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    {
16781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // we should have checked for this previously
16881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        bool isAxisAlignedEllipse = drawState->getViewMatrix().rectStaysRect();
16981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        SkASSERT(paint.isAntiAlias() && isAxisAlignedEllipse);
17081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
17181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#endif
17281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
17381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    const SkMatrix& vm = drawState->getViewMatrix();
17481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrPoint center = GrPoint::Make(ellipse.centerX(), ellipse.centerY());
17581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    vm.mapPoints(&center, 1);
17681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkRect xformedRect;
17781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    vm.mapRect(&xformedRect, ellipse);
17881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
17981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawState::AutoDeviceCoordDraw adcd(drawState);
18081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (!adcd.succeeded()) {
18181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return;
18281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
18381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
18481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // position + edge
18581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    static const GrVertexAttrib kVertexAttribs[] = {
18681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        {kVec2f_GrVertexAttribType, 0},
18781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        {kVec2f_GrVertexAttribType, sizeof(GrPoint)},
18881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        {kVec4f_GrVertexAttribType, 2*sizeof(GrPoint)}
18981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    };
19081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    drawState->setVertexAttribs(kVertexAttribs, SK_ARRAY_COUNT(kVertexAttribs));
19181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    drawState->setAttribIndex(GrDrawState::kPosition_AttribIndex, 0);
19281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrAssert(sizeof(EllipseVertex) == drawState->getVertexSize());
19381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
19481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
19581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (!geo.succeeded()) {
19681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        GrPrintf("Failed to get space for vertices!\n");
19781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        return;
19881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
19981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
20081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(geo.vertices());
20181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
20281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkStrokeRec::Style style = stroke.getStyle();
20381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    bool isStroked = (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style);
20481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    enum {
20581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // the edge effects share this stage with glyph rendering
20681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // (kGlyphMaskStage in GrTextContext) && SW path rendering
20781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // (kPathMaskStage in GrSWMaskHelper)
20881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        kEdgeEffectStage = GrPaint::kTotalStages,
20981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    };
21081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    drawState->setAttribBindings(GrDrawState::kDefault_AttribBindings);
21181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
21281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    GrEffectRef* effect = GrEllipseEdgeEffect::Create(isStroked);
21381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    static const int kEllipseCenterAttrIndex = 1;
21481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    static const int kEllipseEdgeAttrIndex = 2;
21581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    drawState->setEffect(kEdgeEffectStage, effect,
21681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                         kEllipseCenterAttrIndex, kEllipseEdgeAttrIndex)->unref();
21781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
21881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar xRadius = SkScalarHalf(xformedRect.width());
21981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar yRadius = SkScalarHalf(xformedRect.height());
22081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar innerXRadius = 0.0f;
22181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar innerRatio = 1.0f;
22281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
22381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    if (SkStrokeRec::kFill_Style != style) {
22481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        SkScalar strokeWidth = stroke.getWidth();
22581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
22681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // do (potentially) anisotropic mapping
22781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        SkVector scaledStroke;
22881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        scaledStroke.set(strokeWidth, strokeWidth);
22981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        vm.mapVectors(&scaledStroke, 1);
23081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
23181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        if (SkScalarNearlyZero(scaledStroke.length())) {
23281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf);
23381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        } else {
23481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            scaledStroke.scale(0.5f);
23581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        }
23681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
23781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        // this is legit only if scale & translation (which should be the case at the moment)
23881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        if (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style) {
23981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            SkScalar innerYRadius = SkMaxScalar(0, yRadius - scaledStroke.fY);
24081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            if (innerYRadius > SK_ScalarNearlyZero) {
24181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                innerXRadius = SkMaxScalar(0, xRadius - scaledStroke.fX);
24281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org                innerRatio = innerXRadius/innerYRadius;
24381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org            }
24481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        }
24581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        xRadius += scaledStroke.fX;
24681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        yRadius += scaledStroke.fY;
24781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
24881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
24981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar outerRatio = SkScalarDiv(xRadius, yRadius);
25081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
25181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    for (int i = 0; i < 4; ++i) {
25281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        verts[i].fCenter = center;
25381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        verts[i].fOuterXRadius = xRadius + 0.5f;
25481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        verts[i].fOuterXYRatio = outerRatio;
25581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        verts[i].fInnerXRadius = innerXRadius - 0.5f;
25681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        verts[i].fInnerXYRatio = innerRatio;
25781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    }
25881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
25981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar L = -xRadius;
26081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar R = +xRadius;
26181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar T = -yRadius;
26281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    SkScalar B = +yRadius;
26381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
26481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // We've extended the outer x radius out half a pixel to antialias.
26581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // Expand the drawn rect here so all the pixels will be captured.
26681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    L += center.fX - SK_ScalarHalf;
26781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    R += center.fX + SK_ScalarHalf;
26881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    T += center.fY - SK_ScalarHalf;
26981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    B += center.fY + SK_ScalarHalf;
27081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
27181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    verts[0].fPos = SkPoint::Make(L, T);
27281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    verts[1].fPos = SkPoint::Make(R, T);
27381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    verts[2].fPos = SkPoint::Make(L, B);
27481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    verts[3].fPos = SkPoint::Make(R, B);
27581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
27681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4);
27781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}
27881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
279