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(¢er, 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(¢er, 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