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