GrOvalOpFactory.cpp revision 11bf8b2eae7d1780cb969146422a2ab3b933047a
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 107539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon#include "GrBatchFlushState.h" 113e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt#include "GrBatchTest.h" 12eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrGeometryProcessor.h" 13605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h" 1476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt#include "GrProcessor.h" 15ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon#include "GrResourceProvider.h" 16f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org#include "SkRRect.h" 1781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "SkStrokeRec.h" 1816b991390bb988b194a868ab8de66db4c21c7c13bsalomon#include "batches/GrVertexBatch.h" 192d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLFragmentShaderBuilder.h" 20e659a581f63fdccb64dce2dc8a478cf56831feeaegdaniel#include "glsl/GrGLSLGeometryProcessor.h" 21018fb62d12d1febf121fe265da5b6117b86a6541egdaniel#include "glsl/GrGLSLProgramDataManager.h" 220eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel#include "glsl/GrGLSLVarying.h" 232d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel#include "glsl/GrGLSLVertexShaderBuilder.h" 247ea439b2203855db97330b25945b87dd4b170b8begdaniel#include "glsl/GrGLSLUniformHandler.h" 2564c4728c70001ed074fecf5c4e083781987b12e9egdaniel#include "glsl/GrGLSLUtil.h" 26234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org 2776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt// TODO(joshualitt) - Break this file up during GrBatch post implementation cleanup 2876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 2981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgnamespace { 30bb2ff94e223014403f775c3532a25cc25b00c949brianosman 3181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgstruct CircleVertex { 32972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fPos; 33bb2ff94e223014403f775c3532a25cc25b00c949brianosman GrColor fColor; 34972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fOffset; 3581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkScalar fOuterRadius; 3681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkScalar fInnerRadius; 3781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}; 3881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 3981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgstruct EllipseVertex { 40972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fPos; 41bb2ff94e223014403f775c3532a25cc25b00c949brianosman GrColor fColor; 42972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fOffset; 43972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fOuterRadii; 44972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fInnerRadii; 45f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org}; 46f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgstruct DIEllipseVertex { 48972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fPos; 49bb2ff94e223014403f775c3532a25cc25b00c949brianosman GrColor fColor; 50972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fOuterOffset; 51972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fInnerOffset; 525242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org}; 535242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 5481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orginline bool circle_stays_circle(const SkMatrix& m) { 5581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org return m.isSimilarity(); 5681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org} 5781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 5881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org} 5981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 6090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 6190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 6290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/** 63ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * The output of this effect is a modulation of the input color and coverage for a circle. It 64ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * operates in a space normalized by the circle radius (outer radius in the case of a stroke) 65cdaa97bf664e0d584187efc125bfff670a064a9absalomon * with origin at the circle center. Three vertex attributes are used: 66ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * vec2f : position in device space of the bounding geometry vertices 67cdaa97bf664e0d584187efc125bfff670a064a9absalomon * vec4ub: color 68ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * vec4f : (p.xy, outerRad, innerRad) 69ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * p is the position in the normalized space. 70ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * outerRad is the outerRadius in device space. 71ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * innerRad is the innerRadius in normalized space (ignored if not stroking). 7290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org */ 7390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 74cdaa97bf664e0d584187efc125bfff670a064a9absalomonclass CircleGeometryProcessor : public GrGeometryProcessor { 7590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgpublic: 76cdaa97bf664e0d584187efc125bfff670a064a9absalomon CircleGeometryProcessor(bool stroke, const SkMatrix& localMatrix) : fLocalMatrix(localMatrix){ 77cdaa97bf664e0d584187efc125bfff670a064a9absalomon this->initClassID<CircleGeometryProcessor>(); 78cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType, 79cdaa97bf664e0d584187efc125bfff670a064a9absalomon kHigh_GrSLPrecision)); 80cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); 81cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInCircleEdge = &this->addVertexAttrib(Attribute("inCircleEdge", 82cdaa97bf664e0d584187efc125bfff670a064a9absalomon kVec4f_GrVertexAttribType)); 83cdaa97bf664e0d584187efc125bfff670a064a9absalomon fStroke = stroke; 8490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 8590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 8671c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inPosition() const { return fInPosition; } 87bb2ff94e223014403f775c3532a25cc25b00c949brianosman const Attribute* inColor() const { return fInColor; } 8871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inCircleEdge() const { return fInCircleEdge; } 89e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkMatrix& localMatrix() const { return fLocalMatrix; } 90cdaa97bf664e0d584187efc125bfff670a064a9absalomon virtual ~CircleGeometryProcessor() {} 9190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 9236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "CircleEdge"; } 9390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 9457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel class GLSLProcessor : public GrGLSLGeometryProcessor { 9590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org public: 96bb2ff94e223014403f775c3532a25cc25b00c949brianosman GLSLProcessor() {} 9790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 9836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 99cdaa97bf664e0d584187efc125bfff670a064a9absalomon const CircleGeometryProcessor& cgp = args.fGP.cast<CircleGeometryProcessor>(); 1004ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; 1010eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 1027ea439b2203855db97330b25945b87dd4b170b8begdaniel GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 1032dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 104abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 105cdaa97bf664e0d584187efc125bfff670a064a9absalomon varyingHandler->emitAttributes(cgp); 106abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 1078dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel GrGLSLVertToFrag v(kVec4f_GrSLType); 1080eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel varyingHandler->addVarying("CircleEdge", &v); 109cdaa97bf664e0d584187efc125bfff670a064a9absalomon vertBuilder->codeAppendf("%s = %s;", v.vsOut(), cgp.inCircleEdge()->fName); 11090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 1118528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; 112b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt // setup pass through color 113cdaa97bf664e0d584187efc125bfff670a064a9absalomon varyingHandler->addPassThroughAttribute(cgp.inColor(), args.fOutputColor); 1149b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 115abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 116cdaa97bf664e0d584187efc125bfff670a064a9absalomon this->setupPosition(vertBuilder, gpArgs, cgp.inPosition()->fName); 117abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 118abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 1197ea439b2203855db97330b25945b87dd4b170b8begdaniel this->emitTransforms(vertBuilder, 1200eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel varyingHandler, 1217ea439b2203855db97330b25945b87dd4b170b8begdaniel uniformHandler, 1224ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gpArgs->fPositionVar, 123cdaa97bf664e0d584187efc125bfff670a064a9absalomon cgp.inPosition()->fName, 124cdaa97bf664e0d584187efc125bfff670a064a9absalomon cgp.localMatrix(), 1254ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fTransformsIn, 1264ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fTransformsOut); 1274ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel 1284ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn()); 1294ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("float edgeAlpha = clamp(%s.z * (1.0 - d), 0.0, 1.0);", 1304ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel v.fsIn()); 131cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (cgp.fStroke) { 1324ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("float innerAlpha = clamp(%s.z * (d - %s.w), 0.0, 1.0);", 1334ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel v.fsIn(), v.fsIn()); 1344ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("edgeAlpha *= innerAlpha;"); 13590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 1360a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org 1374ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); 13890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 13990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 14046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static void GenKey(const GrGeometryProcessor& gp, 141cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 142b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 143cdaa97bf664e0d584187efc125bfff670a064a9absalomon const CircleGeometryProcessor& cgp = gp.cast<CircleGeometryProcessor>(); 144cdaa97bf664e0d584187efc125bfff670a064a9absalomon uint16_t key = cgp.fStroke ? 0x1 : 0x0; 145cdaa97bf664e0d584187efc125bfff670a064a9absalomon key |= cgp.localMatrix().hasPerspective() ? 0x2 : 0x0; 146b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt b->add32(key); 14790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 14890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 149018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void setData(const GrGLSLProgramDataManager& pdman, 150018fb62d12d1febf121fe265da5b6117b86a6541egdaniel const GrPrimitiveProcessor& gp) override { 1519b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 15290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 153e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt void setTransformData(const GrPrimitiveProcessor& primProc, 154018fb62d12d1febf121fe265da5b6117b86a6541egdaniel const GrGLSLProgramDataManager& pdman, 155e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt int index, 156e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkTArray<const GrCoordTransform*, true>& transforms) override { 157cdaa97bf664e0d584187efc125bfff670a064a9absalomon this->setTransformDataHelper<CircleGeometryProcessor>(primProc, pdman, index, 158cdaa97bf664e0d584187efc125bfff670a064a9absalomon transforms); 159e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt } 160e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt 16190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org private: 162e659a581f63fdccb64dce2dc8a478cf56831feeaegdaniel typedef GrGLSLGeometryProcessor INHERITED; 16390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org }; 16490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 16557d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel void getGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 16657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GLSLProcessor::GenKey(*this, caps, b); 167eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 168eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 16957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override { 17057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel return new GLSLProcessor(); 171eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 17290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 17390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgprivate: 174cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix fLocalMatrix; 17571c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInPosition; 176bb2ff94e223014403f775c3532a25cc25b00c949brianosman const Attribute* fInColor; 17771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInCircleEdge; 178cdaa97bf664e0d584187efc125bfff670a064a9absalomon bool fStroke; 17990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 180b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 18190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 182249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGeometryProcessor INHERITED; 18390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org}; 18490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 185cdaa97bf664e0d584187efc125bfff670a064a9absalomonGR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleGeometryProcessor); 18690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 18706ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrGeometryProcessor> CircleGeometryProcessor::TestCreate(GrProcessorTestData* d) { 18806ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return sk_sp<GrGeometryProcessor>( 18906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman new CircleGeometryProcessor(d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom))); 19090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org} 19190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 19290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 19390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 19490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/** 19590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * The output of this effect is a modulation of the input color and coverage for an axis-aligned 1968be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com * ellipse, specified as a 2D offset from center, and the reciprocals of the outer and inner radii, 1978be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com * in both x and y directions. 1988be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com * 1996bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. 20090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org */ 20190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 202cdaa97bf664e0d584187efc125bfff670a064a9absalomonclass EllipseGeometryProcessor : public GrGeometryProcessor { 20390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgpublic: 204cdaa97bf664e0d584187efc125bfff670a064a9absalomon EllipseGeometryProcessor(bool stroke, const SkMatrix& localMatrix) 205cdaa97bf664e0d584187efc125bfff670a064a9absalomon : fLocalMatrix(localMatrix) { 206cdaa97bf664e0d584187efc125bfff670a064a9absalomon this->initClassID<EllipseGeometryProcessor>(); 207cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); 208cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); 209cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInEllipseOffset = &this->addVertexAttrib(Attribute("inEllipseOffset", 210cdaa97bf664e0d584187efc125bfff670a064a9absalomon kVec2f_GrVertexAttribType)); 211cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInEllipseRadii = &this->addVertexAttrib(Attribute("inEllipseRadii", 212cdaa97bf664e0d584187efc125bfff670a064a9absalomon kVec4f_GrVertexAttribType)); 213cdaa97bf664e0d584187efc125bfff670a064a9absalomon fStroke = stroke; 21490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 21590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 216cdaa97bf664e0d584187efc125bfff670a064a9absalomon virtual ~EllipseGeometryProcessor() {} 21790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 21836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "EllipseEdge"; } 2192dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 22071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inPosition() const { return fInPosition; } 221bb2ff94e223014403f775c3532a25cc25b00c949brianosman const Attribute* inColor() const { return fInColor; } 22271c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inEllipseOffset() const { return fInEllipseOffset; } 22371c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inEllipseRadii() const { return fInEllipseRadii; } 224e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkMatrix& localMatrix() const { return fLocalMatrix; } 22590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 22657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel class GLSLProcessor : public GrGLSLGeometryProcessor { 22790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org public: 228bb2ff94e223014403f775c3532a25cc25b00c949brianosman GLSLProcessor() {} 22990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 23036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 231cdaa97bf664e0d584187efc125bfff670a064a9absalomon const EllipseGeometryProcessor& egp = args.fGP.cast<EllipseGeometryProcessor>(); 2324ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; 2330eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 2347ea439b2203855db97330b25945b87dd4b170b8begdaniel GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 23590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 236abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 237cdaa97bf664e0d584187efc125bfff670a064a9absalomon varyingHandler->emitAttributes(egp); 238abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 2398dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel GrGLSLVertToFrag ellipseOffsets(kVec2f_GrSLType); 2400eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel varyingHandler->addVarying("EllipseOffsets", &ellipseOffsets); 2414ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel vertBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(), 242cdaa97bf664e0d584187efc125bfff670a064a9absalomon egp.inEllipseOffset()->fName); 24390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 2448dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel GrGLSLVertToFrag ellipseRadii(kVec4f_GrSLType); 2450eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel varyingHandler->addVarying("EllipseRadii", &ellipseRadii); 2464ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel vertBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), 247cdaa97bf664e0d584187efc125bfff670a064a9absalomon egp.inEllipseRadii()->fName); 2482dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 2498528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; 250b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt // setup pass through color 251cdaa97bf664e0d584187efc125bfff670a064a9absalomon varyingHandler->addPassThroughAttribute(egp.inColor(), args.fOutputColor); 2529b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 253abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 254cdaa97bf664e0d584187efc125bfff670a064a9absalomon this->setupPosition(vertBuilder, gpArgs, egp.inPosition()->fName); 255abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 256abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 2577ea439b2203855db97330b25945b87dd4b170b8begdaniel this->emitTransforms(vertBuilder, 2580eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel varyingHandler, 2597ea439b2203855db97330b25945b87dd4b170b8begdaniel uniformHandler, 2604ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gpArgs->fPositionVar, 261cdaa97bf664e0d584187efc125bfff670a064a9absalomon egp.inPosition()->fName, 262cdaa97bf664e0d584187efc125bfff670a064a9absalomon egp.localMatrix(), 2634ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fTransformsIn, 2644ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fTransformsOut); 2654973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 2668be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com // for outer curve 2674ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(), 2684ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel ellipseRadii.fsIn()); 2694ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;"); 2704ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn()); 2714ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("float grad_dot = dot(grad, grad);"); 27274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt 2731b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org // avoid calling inversesqrt on zero. 2744ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);"); 2754ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("float invlen = inversesqrt(grad_dot);"); 276c6052ac41a704cc64f16c49780a8fd05c7f550d4brianosman fragBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);"); 277f58d8540a42e5138e7cdb1dd1e0b4de0fa3c4a10jvanverth@google.com 2786bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // for inner curve 279cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (egp.fStroke) { 2804ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("scaledOffset = %s*%s.zw;", 2814ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel ellipseOffsets.fsIn(), ellipseRadii.fsIn()); 2824ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;"); 2834ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;", 2844ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel ellipseRadii.fsIn()); 2854ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));"); 2864ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);"); 28790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 28890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 2894ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); 29090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 29190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 29246d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static void GenKey(const GrGeometryProcessor& gp, 293cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 294b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 295cdaa97bf664e0d584187efc125bfff670a064a9absalomon const EllipseGeometryProcessor& egp = gp.cast<EllipseGeometryProcessor>(); 296cdaa97bf664e0d584187efc125bfff670a064a9absalomon uint16_t key = egp.fStroke ? 0x1 : 0x0; 297cdaa97bf664e0d584187efc125bfff670a064a9absalomon key |= egp.localMatrix().hasPerspective() ? 0x2 : 0x0; 298b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt b->add32(key); 29990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 30090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 301018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcessor& gp) override { 30290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 30390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 304e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt void setTransformData(const GrPrimitiveProcessor& primProc, 305018fb62d12d1febf121fe265da5b6117b86a6541egdaniel const GrGLSLProgramDataManager& pdman, 306e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt int index, 307e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkTArray<const GrCoordTransform*, true>& transforms) override { 308cdaa97bf664e0d584187efc125bfff670a064a9absalomon this->setTransformDataHelper<EllipseGeometryProcessor>(primProc, pdman, index, 309cdaa97bf664e0d584187efc125bfff670a064a9absalomon transforms); 310e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt } 311e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt 31290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org private: 313e659a581f63fdccb64dce2dc8a478cf56831feeaegdaniel typedef GrGLSLGeometryProcessor INHERITED; 31490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org }; 31590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 31657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel void getGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 31757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GLSLProcessor::GenKey(*this, caps, b); 318eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 319eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 32057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override { 32157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel return new GLSLProcessor(); 322eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 323eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 32490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgprivate: 32571c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInPosition; 326bb2ff94e223014403f775c3532a25cc25b00c949brianosman const Attribute* fInColor; 32771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInEllipseOffset; 32871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInEllipseRadii; 329e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt SkMatrix fLocalMatrix; 33090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org bool fStroke; 33190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 332b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 33390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 334249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGeometryProcessor INHERITED; 33590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org}; 33690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 337cdaa97bf664e0d584187efc125bfff670a064a9absalomonGR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseGeometryProcessor); 33890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 33906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrGeometryProcessor> EllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) { 34006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return sk_sp<GrGeometryProcessor>( 34106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman new EllipseGeometryProcessor(d->fRandom->nextBool(), GrTest::TestMatrix(d->fRandom))); 34290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org} 34390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 34490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 34590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 3465242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org/** 3476fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com * The output of this effect is a modulation of the input color and coverage for an ellipse, 3485242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * specified as a 2D offset from center for both the outer and inner paths (if stroked). The 3495242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge corrected by 3505242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * using differentials. 3515242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * 3525242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * The result is device-independent and can be used with any affine matrix. 3535242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org */ 3545242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 355cdaa97bf664e0d584187efc125bfff670a064a9absalomonenum class DIEllipseStyle { kStroke = 0, kHairline, kFill }; 3565242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 357cdaa97bf664e0d584187efc125bfff670a064a9absalomonclass DIEllipseGeometryProcessor : public GrGeometryProcessor { 358cdaa97bf664e0d584187efc125bfff670a064a9absalomonpublic: 359cdaa97bf664e0d584187efc125bfff670a064a9absalomon DIEllipseGeometryProcessor(const SkMatrix& viewMatrix, DIEllipseStyle style) 360cdaa97bf664e0d584187efc125bfff670a064a9absalomon : fViewMatrix(viewMatrix) { 361cdaa97bf664e0d584187efc125bfff670a064a9absalomon this->initClassID<DIEllipseGeometryProcessor>(); 362cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType, 363cdaa97bf664e0d584187efc125bfff670a064a9absalomon kHigh_GrSLPrecision)); 364cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInColor = &this->addVertexAttrib(Attribute("inColor", kVec4ub_GrVertexAttribType)); 365cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInEllipseOffsets0 = &this->addVertexAttrib(Attribute("inEllipseOffsets0", 366cdaa97bf664e0d584187efc125bfff670a064a9absalomon kVec2f_GrVertexAttribType)); 367cdaa97bf664e0d584187efc125bfff670a064a9absalomon fInEllipseOffsets1 = &this->addVertexAttrib(Attribute("inEllipseOffsets1", 368cdaa97bf664e0d584187efc125bfff670a064a9absalomon kVec2f_GrVertexAttribType)); 369cdaa97bf664e0d584187efc125bfff670a064a9absalomon fStyle = style; 3705242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 3715242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 372cdaa97bf664e0d584187efc125bfff670a064a9absalomon 373cdaa97bf664e0d584187efc125bfff670a064a9absalomon virtual ~DIEllipseGeometryProcessor() {} 3745242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 37536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "DIEllipseEdge"; } 3765242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 37771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inPosition() const { return fInPosition; } 378bb2ff94e223014403f775c3532a25cc25b00c949brianosman const Attribute* inColor() const { return fInColor; } 37971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inEllipseOffsets0() const { return fInEllipseOffsets0; } 38071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inEllipseOffsets1() const { return fInEllipseOffsets1; } 381e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt const SkMatrix& viewMatrix() const { return fViewMatrix; } 3829d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 38357d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel class GLSLProcessor : public GrGLSLGeometryProcessor { 3845242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org public: 38557d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GLSLProcessor() 386bb2ff94e223014403f775c3532a25cc25b00c949brianosman : fViewMatrix(SkMatrix::InvalidMatrix()) {} 3875242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 388465283cdf98ed9ab5285ca7b9814e430fca1d452joshualitt void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { 389cdaa97bf664e0d584187efc125bfff670a064a9absalomon const DIEllipseGeometryProcessor& diegp = args.fGP.cast<DIEllipseGeometryProcessor>(); 3904ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; 3910eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 3927ea439b2203855db97330b25945b87dd4b170b8begdaniel GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 3935242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 394abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 395cdaa97bf664e0d584187efc125bfff670a064a9absalomon varyingHandler->emitAttributes(diegp); 396abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 3978dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel GrGLSLVertToFrag offsets0(kVec2f_GrSLType); 3980eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel varyingHandler->addVarying("EllipseOffsets0", &offsets0); 3994ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel vertBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), 400cdaa97bf664e0d584187efc125bfff670a064a9absalomon diegp.inEllipseOffsets0()->fName); 40174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt 4028dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel GrGLSLVertToFrag offsets1(kVec2f_GrSLType); 4030eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel varyingHandler->addVarying("EllipseOffsets1", &offsets1); 4044ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel vertBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), 405cdaa97bf664e0d584187efc125bfff670a064a9absalomon diegp.inEllipseOffsets1()->fName); 4062dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 4078528541dd7f09f5bd76f3f1ce5f45d08ac7347c7cdalton GrGLSLPPFragmentBuilder* fragBuilder = args.fFragBuilder; 408cdaa97bf664e0d584187efc125bfff670a064a9absalomon varyingHandler->addPassThroughAttribute(diegp.inColor(), args.fOutputColor); 4099b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 410abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 4117ea439b2203855db97330b25945b87dd4b170b8begdaniel this->setupPosition(vertBuilder, 4127ea439b2203855db97330b25945b87dd4b170b8begdaniel uniformHandler, 4134ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gpArgs, 414cdaa97bf664e0d584187efc125bfff670a064a9absalomon diegp.inPosition()->fName, 415cdaa97bf664e0d584187efc125bfff670a064a9absalomon diegp.viewMatrix(), 4165559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt &fViewMatrixUniform); 417abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 418abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 4197ea439b2203855db97330b25945b87dd4b170b8begdaniel this->emitTransforms(vertBuilder, 4200eafe79f42e3c675f3c504aed4a41abf511df2b7egdaniel varyingHandler, 4217ea439b2203855db97330b25945b87dd4b170b8begdaniel uniformHandler, 4224ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel gpArgs->fPositionVar, 423cdaa97bf664e0d584187efc125bfff670a064a9absalomon diegp.inPosition()->fName, 4244ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fTransformsIn, 4254ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel args.fTransformsOut); 4264ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel 4274ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel SkAssertResult(fragBuilder->enableFeature( 4282d721d33aad192cc8a7a1321504b39bdca2a57ceegdaniel GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 4295242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // for outer curve 4304ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn()); 4314ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;"); 4324ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn()); 4334ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn()); 4344ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y," 4354ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);", 436cdaa97bf664e0d584187efc125bfff670a064a9absalomon offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), 437cdaa97bf664e0d584187efc125bfff670a064a9absalomon offsets0.fsIn()); 4384ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel 4394ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("float grad_dot = dot(grad, grad);"); 4401b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org // avoid calling inversesqrt on zero. 4414ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);"); 4424ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("float invlen = inversesqrt(grad_dot);"); 443cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (DIEllipseStyle::kHairline == diegp.fStyle) { 4445242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // can probably do this with one step 4454ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);"); 4464ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);"); 4475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } else { 4484ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);"); 4495242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 4505242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 4515242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // for inner curve 452cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (DIEllipseStyle::kStroke == diegp.fStyle) { 4534ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn()); 4544ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;"); 4554ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn()); 4564ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn()); 4574ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y," 4584ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);", 4594ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(), 4604ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel offsets1.fsIn()); 4614ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));"); 4624ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);"); 4635242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 4645242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 4654ca2e6034365ad280ec64473f7f1d72ebd8335e4egdaniel fragBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); 4665242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 4675242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 46846d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static void GenKey(const GrGeometryProcessor& gp, 469cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 470b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 471cdaa97bf664e0d584187efc125bfff670a064a9absalomon const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>(); 472cdaa97bf664e0d584187efc125bfff670a064a9absalomon uint16_t key = static_cast<uint16_t>(diegp.fStyle); 473cdaa97bf664e0d584187efc125bfff670a064a9absalomon key |= ComputePosKey(diegp.viewMatrix()) << 10; 474b8c241ad099f3f0c2cbf3e7c10f5f6207175d490joshualitt b->add32(key); 4755242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 4765242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 477018fb62d12d1febf121fe265da5b6117b86a6541egdaniel void setData(const GrGLSLProgramDataManager& pdman, 478018fb62d12d1febf121fe265da5b6117b86a6541egdaniel const GrPrimitiveProcessor& gp) override { 479cdaa97bf664e0d584187efc125bfff670a064a9absalomon const DIEllipseGeometryProcessor& diegp = gp.cast<DIEllipseGeometryProcessor>(); 4805559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt 481cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!diegp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(diegp.viewMatrix())) { 482cdaa97bf664e0d584187efc125bfff670a064a9absalomon fViewMatrix = diegp.viewMatrix(); 483018fb62d12d1febf121fe265da5b6117b86a6541egdaniel float viewMatrix[3 * 3]; 48464c4728c70001ed074fecf5c4e083781987b12e9egdaniel GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); 4855559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); 4865559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt } 4875242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 4885242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 4895242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org private: 4905559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt SkMatrix fViewMatrix; 4915559ca2a18687ef16b2fc92d8fcacbc1c3e93d54joshualitt UniformHandle fViewMatrixUniform; 4929b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 493e659a581f63fdccb64dce2dc8a478cf56831feeaegdaniel typedef GrGLSLGeometryProcessor INHERITED; 4945242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org }; 4955242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 49657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel void getGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override { 49757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GLSLProcessor::GenKey(*this, caps, b); 498eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 499eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 50057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLPrimitiveProcessor* createGLSLInstance(const GrGLSLCaps&) const override { 50157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel return new GLSLProcessor(); 502eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 503eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 5045242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgprivate: 50571c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInPosition; 506bb2ff94e223014403f775c3532a25cc25b00c949brianosman const Attribute* fInColor; 50771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInEllipseOffsets0; 50871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInEllipseOffsets1; 509cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix fViewMatrix; 510cdaa97bf664e0d584187efc125bfff670a064a9absalomon DIEllipseStyle fStyle; 5115242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 512b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 5135242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 514249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGeometryProcessor INHERITED; 5155242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org}; 5165242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 517cdaa97bf664e0d584187efc125bfff670a064a9absalomonGR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseGeometryProcessor); 5185242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 51906ca8ec87cf6fab57cadd043a5ac18c4154a4129bungemansk_sp<GrGeometryProcessor> DIEllipseGeometryProcessor::TestCreate(GrProcessorTestData* d) { 52006ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman return sk_sp<GrGeometryProcessor>( 52106ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman new DIEllipseGeometryProcessor(GrTest::TestMatrix(d->fRandom), 52206ca8ec87cf6fab57cadd043a5ac18c4154a4129bungeman (DIEllipseStyle)(d->fRandom->nextRangeU(0,2)))); 5235242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org} 5245242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 5255242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 5265242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 52711bf8b2eae7d1780cb969146422a2ab3b933047absalomonclass CircleBatch : public GrVertexBatch { 52811bf8b2eae7d1780cb969146422a2ab3b933047absalomonpublic: 52911bf8b2eae7d1780cb969146422a2ab3b933047absalomon DEFINE_BATCH_CLASS_ID 53081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 53111bf8b2eae7d1780cb969146422a2ab3b933047absalomon CircleBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& circle, 53211bf8b2eae7d1780cb969146422a2ab3b933047absalomon const SkStrokeRec& stroke) 53311bf8b2eae7d1780cb969146422a2ab3b933047absalomon : INHERITED(ClassID()) 53411bf8b2eae7d1780cb969146422a2ab3b933047absalomon , fViewMatrixIfUsingLocalCoords(viewMatrix) { 53511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); 53611bf8b2eae7d1780cb969146422a2ab3b933047absalomon viewMatrix.mapPoints(¢er, 1); 53711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width())); 53811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth()); 539f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 54011bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkStrokeRec::Style style = stroke.getStyle(); 54111bf8b2eae7d1780cb969146422a2ab3b933047absalomon bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 54211bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkStrokeRec::kHairline_Style == style; 54311bf8b2eae7d1780cb969146422a2ab3b933047absalomon bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 5441b55a963a2374a14bb82eb887bb99ee91680f0ebreed 54511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar innerRadius = 0.0f; 54611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar outerRadius = radius; 54711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar halfWidth = 0; 54811bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (hasStroke) { 54911bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (SkScalarNearlyZero(strokeWidth)) { 55011bf8b2eae7d1780cb969146422a2ab3b933047absalomon halfWidth = SK_ScalarHalf; 55111bf8b2eae7d1780cb969146422a2ab3b933047absalomon } else { 55211bf8b2eae7d1780cb969146422a2ab3b933047absalomon halfWidth = SkScalarHalf(strokeWidth); 55311bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 55476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 55511bf8b2eae7d1780cb969146422a2ab3b933047absalomon outerRadius += halfWidth; 55611bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (isStrokeOnly) { 55711bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerRadius = radius - halfWidth; 55811bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 55911bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 5605fd209e8ee477c703bc5c11b008f247d515fc0fcbsalomon 56111bf8b2eae7d1780cb969146422a2ab3b933047absalomon // The radii are outset for two reasons. First, it allows the shader to simply perform 56211bf8b2eae7d1780cb969146422a2ab3b933047absalomon // simpler computation because the computed alpha is zero, rather than 50%, at the radius. 56311bf8b2eae7d1780cb969146422a2ab3b933047absalomon // Second, the outer radius is used to compute the verts of the bounding box that is 56411bf8b2eae7d1780cb969146422a2ab3b933047absalomon // rendered and the outset ensures the box will cover all partially covered by the circle. 56511bf8b2eae7d1780cb969146422a2ab3b933047absalomon outerRadius += SK_ScalarHalf; 56611bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerRadius -= SK_ScalarHalf; 5677f06c6947a3bef78dc57b9252779567c33604c90bsalomon 56811bf8b2eae7d1780cb969146422a2ab3b933047absalomon fGeoData.emplace_back(Geometry { 56911bf8b2eae7d1780cb969146422a2ab3b933047absalomon color, 57011bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerRadius, 57111bf8b2eae7d1780cb969146422a2ab3b933047absalomon outerRadius, 57211bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius, 57311bf8b2eae7d1780cb969146422a2ab3b933047absalomon center.fX + outerRadius, center.fY + outerRadius) 57411bf8b2eae7d1780cb969146422a2ab3b933047absalomon }); 57511bf8b2eae7d1780cb969146422a2ab3b933047absalomon this->setBounds(fGeoData.back().fDevBounds); 57611bf8b2eae7d1780cb969146422a2ab3b933047absalomon fStroked = isStrokeOnly && innerRadius > 0; 577df4f47b8ff6378c4d8f775dcb3169ac7c64f2510benjaminwagner } 57811bf8b2eae7d1780cb969146422a2ab3b933047absalomon 57936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "CircleBatch"; } 58076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 581e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips SkString dumpInfo() const override { 582e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips SkString string; 583e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips for (int i = 0; i < fGeoData.count(); ++i) { 584e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips string.appendf("Color: 0x%08x Rect [L: %.2f, T: %.2f, R: %.2f, B: %.2f]," 585e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips "InnerRad: %.2f, OuterRad: %.2f\n", 586e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips fGeoData[i].fColor, 587e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips fGeoData[i].fDevBounds.fLeft, fGeoData[i].fDevBounds.fTop, 588e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips fGeoData[i].fDevBounds.fRight, fGeoData[i].fDevBounds.fBottom, 589e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips fGeoData[i].fInnerRadius, 590e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips fGeoData[i].fOuterRadius); 591e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips } 592e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips string.append(INHERITED::dumpInfo()); 593e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips return string; 594e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips } 595e004bfc0a5e28cc083158f1a75e981ffd58a8134robertphillips 5969d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary void computePipelineOptimizations(GrInitInvariantOutput* color, 597ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrInitInvariantOutput* coverage, 598ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrBatchToXPOverrides* overrides) const override { 59976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 600ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas color->setKnownFourComponents(fGeoData[0].fColor); 601ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas coverage->setUnknownSingleComponent(); 60276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 60376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 604e46f9feb44780a6269c6dcfe993f4215427fd98ebsalomonprivate: 605ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 606cdaa97bf664e0d584187efc125bfff670a064a9absalomon // Handle any overrides that affect our GP. 607ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas overrides.getOverrideColorIfSet(&fGeoData[0].fColor); 608cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!overrides.readsLocalCoords()) { 609cdaa97bf664e0d584187efc125bfff670a064a9absalomon fViewMatrixIfUsingLocalCoords.reset(); 610cdaa97bf664e0d584187efc125bfff670a064a9absalomon } 61176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 61276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 613144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt void onPrepareDraws(Target* target) const override { 614cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix localMatrix; 615cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { 61676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return; 61776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 61876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 61976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 620cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(fStroked, localMatrix)); 62176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 62276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 62376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 62476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(vertexStride == sizeof(CircleVertex)); 625b5238a7571c243ba4a154a62575570c3078b3741bsalomon QuadHelper helper; 6267539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(target, vertexStride, 627b5238a7571c243ba4a154a62575570c3078b3741bsalomon instanceCount)); 628b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts) { 6294b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 6304b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 6314b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 63276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 633144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt const Geometry& geom = fGeoData[i]; 63476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 635bb2ff94e223014403f775c3532a25cc25b00c949brianosman GrColor color = geom.fColor; 636b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar innerRadius = geom.fInnerRadius; 637b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar outerRadius = geom.fOuterRadius; 63876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 639b5238a7571c243ba4a154a62575570c3078b3741bsalomon const SkRect& bounds = geom.fDevBounds; 64076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 64176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // The inner radius in the vertex data must be specified in normalized space. 64276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt innerRadius = innerRadius / outerRadius; 64376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); 644bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[0].fColor = color; 64576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOffset = SkPoint::Make(-1, -1); 64676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOuterRadius = outerRadius; 64776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fInnerRadius = innerRadius; 64876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 64976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); 650bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[1].fColor = color; 65176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOffset = SkPoint::Make(-1, 1); 65276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOuterRadius = outerRadius; 65376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fInnerRadius = innerRadius; 65476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 65576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); 656bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[2].fColor = color; 65776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOffset = SkPoint::Make(1, 1); 65876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOuterRadius = outerRadius; 65976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fInnerRadius = innerRadius; 66076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 66176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); 662bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[3].fColor = color; 66376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOffset = SkPoint::Make(1, -1); 66476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOuterRadius = outerRadius; 66576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fInnerRadius = innerRadius; 66676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 667b5238a7571c243ba4a154a62575570c3078b3741bsalomon verts += kVerticesPerQuad; 66876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 669342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon helper.recordDraw(target, gp); 67076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 67176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 672cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 673abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon CircleBatch* that = t->cast<CircleBatch>(); 674abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 675abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon that->bounds(), caps)) { 6768cab9a7685e872427e6f0388f149575a9b6016eejoshualitt return false; 6778cab9a7685e872427e6f0388f149575a9b6016eejoshualitt } 6788cab9a7685e872427e6f0388f149575a9b6016eejoshualitt 679cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (this->fStroked != that->fStroked) { 68076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 68176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 68276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 683cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { 68476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 68576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 68676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 687cdaa97bf664e0d584187efc125bfff670a064a9absalomon fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 68899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 68976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 69076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 69176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 69211bf8b2eae7d1780cb969146422a2ab3b933047absalomon struct Geometry { 69311bf8b2eae7d1780cb969146422a2ab3b933047absalomon GrColor fColor; 69411bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fInnerRadius; 69511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fOuterRadius; 69611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect fDevBounds; 69711bf8b2eae7d1780cb969146422a2ab3b933047absalomon }; 69811bf8b2eae7d1780cb969146422a2ab3b933047absalomon 699cdaa97bf664e0d584187efc125bfff670a064a9absalomon bool fStroked; 700cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix fViewMatrixIfUsingLocalCoords; 70176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 7021b55a963a2374a14bb82eb887bb99ee91680f0ebreed 7031b55a963a2374a14bb82eb887bb99ee91680f0ebreed typedef GrVertexBatch INHERITED; 70476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 70576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 706f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 707f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 708abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonclass EllipseBatch : public GrVertexBatch { 70976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittpublic: 7101b55a963a2374a14bb82eb887bb99ee91680f0ebreed DEFINE_BATCH_CLASS_ID 71111bf8b2eae7d1780cb969146422a2ab3b933047absalomon static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& ellipse, 71211bf8b2eae7d1780cb969146422a2ab3b933047absalomon const SkStrokeRec& stroke) { 71311bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkASSERT(viewMatrix.rectStaysRect()); 71411bf8b2eae7d1780cb969146422a2ab3b933047absalomon 71511bf8b2eae7d1780cb969146422a2ab3b933047absalomon // do any matrix crunching before we reset the draw state for device coords 71611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); 71711bf8b2eae7d1780cb969146422a2ab3b933047absalomon viewMatrix.mapPoints(¢er, 1); 71811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar ellipseXRadius = SkScalarHalf(ellipse.width()); 71911bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar ellipseYRadius = SkScalarHalf(ellipse.height()); 72011bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*ellipseXRadius + 72111bf8b2eae7d1780cb969146422a2ab3b933047absalomon viewMatrix[SkMatrix::kMSkewY]*ellipseYRadius); 72211bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*ellipseXRadius + 72311bf8b2eae7d1780cb969146422a2ab3b933047absalomon viewMatrix[SkMatrix::kMScaleY]*ellipseYRadius); 72411bf8b2eae7d1780cb969146422a2ab3b933047absalomon 72511bf8b2eae7d1780cb969146422a2ab3b933047absalomon // do (potentially) anisotropic mapping of stroke 72611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkVector scaledStroke; 72711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar strokeWidth = stroke.getWidth(); 72811bf8b2eae7d1780cb969146422a2ab3b933047absalomon scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] + 72911bf8b2eae7d1780cb969146422a2ab3b933047absalomon viewMatrix[SkMatrix::kMSkewY])); 73011bf8b2eae7d1780cb969146422a2ab3b933047absalomon scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] + 73111bf8b2eae7d1780cb969146422a2ab3b933047absalomon viewMatrix[SkMatrix::kMScaleY])); 73211bf8b2eae7d1780cb969146422a2ab3b933047absalomon 73311bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkStrokeRec::Style style = stroke.getStyle(); 73411bf8b2eae7d1780cb969146422a2ab3b933047absalomon bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 73511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkStrokeRec::kHairline_Style == style; 73611bf8b2eae7d1780cb969146422a2ab3b933047absalomon bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 73711bf8b2eae7d1780cb969146422a2ab3b933047absalomon 73811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar innerXRadius = 0; 73911bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar innerYRadius = 0; 74011bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (hasStroke) { 74111bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (SkScalarNearlyZero(scaledStroke.length())) { 74211bf8b2eae7d1780cb969146422a2ab3b933047absalomon scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); 74311bf8b2eae7d1780cb969146422a2ab3b933047absalomon } else { 74411bf8b2eae7d1780cb969146422a2ab3b933047absalomon scaledStroke.scale(SK_ScalarHalf); 74511bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 7465fd209e8ee477c703bc5c11b008f247d515fc0fcbsalomon 74711bf8b2eae7d1780cb969146422a2ab3b933047absalomon // we only handle thick strokes for near-circular ellipses 74811bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (scaledStroke.length() > SK_ScalarHalf && 74911bf8b2eae7d1780cb969146422a2ab3b933047absalomon (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) { 75011bf8b2eae7d1780cb969146422a2ab3b933047absalomon return nullptr; 75111bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 7527f06c6947a3bef78dc57b9252779567c33604c90bsalomon 75311bf8b2eae7d1780cb969146422a2ab3b933047absalomon // we don't handle it if curvature of the stroke is less than curvature of the ellipse 75411bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY)*xRadius || 75511bf8b2eae7d1780cb969146422a2ab3b933047absalomon scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX)*yRadius) { 75611bf8b2eae7d1780cb969146422a2ab3b933047absalomon return nullptr; 75711bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 75811bf8b2eae7d1780cb969146422a2ab3b933047absalomon 75911bf8b2eae7d1780cb969146422a2ab3b933047absalomon // this is legit only if scale & translation (which should be the case at the moment) 76011bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (isStrokeOnly) { 76111bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerXRadius = xRadius - scaledStroke.fX; 76211bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerYRadius = yRadius - scaledStroke.fY; 76311bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 76411bf8b2eae7d1780cb969146422a2ab3b933047absalomon 76511bf8b2eae7d1780cb969146422a2ab3b933047absalomon xRadius += scaledStroke.fX; 76611bf8b2eae7d1780cb969146422a2ab3b933047absalomon yRadius += scaledStroke.fY; 76711bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 76811bf8b2eae7d1780cb969146422a2ab3b933047absalomon 76911bf8b2eae7d1780cb969146422a2ab3b933047absalomon EllipseBatch* batch = new EllipseBatch(); 77011bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->fGeoData.emplace_back(Geometry { 77111bf8b2eae7d1780cb969146422a2ab3b933047absalomon color, 77211bf8b2eae7d1780cb969146422a2ab3b933047absalomon xRadius, 77311bf8b2eae7d1780cb969146422a2ab3b933047absalomon yRadius, 77411bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerXRadius, 77511bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerYRadius, 77611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRadius, 77711bf8b2eae7d1780cb969146422a2ab3b933047absalomon center.fX + xRadius, center.fY + yRadius) 77811bf8b2eae7d1780cb969146422a2ab3b933047absalomon }); 77911bf8b2eae7d1780cb969146422a2ab3b933047absalomon 78011bf8b2eae7d1780cb969146422a2ab3b933047absalomon // Outset bounds to include half-pixel width antialiasing. 78111bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->fGeoData[0].fDevBounds.outset(SK_ScalarHalf, SK_ScalarHalf); 78211bf8b2eae7d1780cb969146422a2ab3b933047absalomon 78311bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->fStroked = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; 78411bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->fViewMatrixIfUsingLocalCoords = viewMatrix; 78511bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->setBounds(batch->fGeoData.back().fDevBounds); 78611bf8b2eae7d1780cb969146422a2ab3b933047absalomon return batch; 787cdaa97bf664e0d584187efc125bfff670a064a9absalomon } 78876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 78936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "EllipseBatch"; } 79076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 7919d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary void computePipelineOptimizations(GrInitInvariantOutput* color, 792ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrInitInvariantOutput* coverage, 793ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrBatchToXPOverrides* overrides) const override { 79476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 795ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas color->setKnownFourComponents(fGeoData[0].fColor); 796ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas coverage->setUnknownSingleComponent(); 79776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 79876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 799e46f9feb44780a6269c6dcfe993f4215427fd98ebsalomonprivate: 80011bf8b2eae7d1780cb969146422a2ab3b933047absalomon EllipseBatch() : INHERITED(ClassID()) {} 80111bf8b2eae7d1780cb969146422a2ab3b933047absalomon 802ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 803cdaa97bf664e0d584187efc125bfff670a064a9absalomon // Handle any overrides that affect our GP. 804ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas if (!overrides.readsCoverage()) { 80576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 80676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 807cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!overrides.readsLocalCoords()) { 808cdaa97bf664e0d584187efc125bfff670a064a9absalomon fViewMatrixIfUsingLocalCoords.reset(); 809cdaa97bf664e0d584187efc125bfff670a064a9absalomon } 81076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 81176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 812144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt void onPrepareDraws(Target* target) const override { 813cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix localMatrix; 814cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { 81576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return; 81676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 81776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 81876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 819cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkAutoTUnref<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix)); 82076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 82176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 822b5238a7571c243ba4a154a62575570c3078b3741bsalomon QuadHelper helper; 82376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 82419e0058a650a9e4dc9c35ed26c5e91916bcc0601joshualitt SkASSERT(vertexStride == sizeof(EllipseVertex)); 825b5238a7571c243ba4a154a62575570c3078b3741bsalomon EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( 8267539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon helper.init(target, vertexStride, instanceCount)); 827b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts) { 8284b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 8294b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 8304b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 83176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 832144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt const Geometry& geom = fGeoData[i]; 83376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 834bb2ff94e223014403f775c3532a25cc25b00c949brianosman GrColor color = geom.fColor; 835b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar xRadius = geom.fXRadius; 836b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar yRadius = geom.fYRadius; 83776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 83876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Compute the reciprocals of the radii here to save time in the shader 83976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar xRadRecip = SkScalarInvert(xRadius); 84076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yRadRecip = SkScalarInvert(yRadius); 841b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar xInnerRadRecip = SkScalarInvert(geom.fInnerXRadius); 842b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar yInnerRadRecip = SkScalarInvert(geom.fInnerYRadius); 84376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 844b5238a7571c243ba4a154a62575570c3078b3741bsalomon const SkRect& bounds = geom.fDevBounds; 84576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 846977996dd0e0c6e6686a980a23e97e6fb5da1a592vjiaoblack // fOffsets are expanded from xyRadii to include the half-pixel antialiasing width. 847977996dd0e0c6e6686a980a23e97e6fb5da1a592vjiaoblack SkScalar xMaxOffset = xRadius + SK_ScalarHalf; 848977996dd0e0c6e6686a980a23e97e6fb5da1a592vjiaoblack SkScalar yMaxOffset = yRadius + SK_ScalarHalf; 849977996dd0e0c6e6686a980a23e97e6fb5da1a592vjiaoblack 85076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // The inner radius in the vertex data must be specified in normalized space. 85176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); 852bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[0].fColor = color; 853977996dd0e0c6e6686a980a23e97e6fb5da1a592vjiaoblack verts[0].fOffset = SkPoint::Make(-xMaxOffset, -yMaxOffset); 85476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 85576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 85676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 85776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); 858bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[1].fColor = color; 859977996dd0e0c6e6686a980a23e97e6fb5da1a592vjiaoblack verts[1].fOffset = SkPoint::Make(-xMaxOffset, yMaxOffset); 86076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 86176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 86276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 86376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); 864bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[2].fColor = color; 865977996dd0e0c6e6686a980a23e97e6fb5da1a592vjiaoblack verts[2].fOffset = SkPoint::Make(xMaxOffset, yMaxOffset); 86676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 86776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 86876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 86976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); 870bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[3].fColor = color; 871977996dd0e0c6e6686a980a23e97e6fb5da1a592vjiaoblack verts[3].fOffset = SkPoint::Make(xMaxOffset, -yMaxOffset); 87276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 87376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 87476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 875b5238a7571c243ba4a154a62575570c3078b3741bsalomon verts += kVerticesPerQuad; 87676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 877342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon helper.recordDraw(target, gp); 87876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 87976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 880cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 881abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon EllipseBatch* that = t->cast<EllipseBatch>(); 882abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 883abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 884abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon that->bounds(), caps)) { 8858cab9a7685e872427e6f0388f149575a9b6016eejoshualitt return false; 8868cab9a7685e872427e6f0388f149575a9b6016eejoshualitt } 8878cab9a7685e872427e6f0388f149575a9b6016eejoshualitt 888cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (fStroked != that->fStroked) { 88976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 89076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 89176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 892cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { 89376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 89476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 89576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 896cdaa97bf664e0d584187efc125bfff670a064a9absalomon fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 89799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 89876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 89976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 90076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 90111bf8b2eae7d1780cb969146422a2ab3b933047absalomon struct Geometry { 90211bf8b2eae7d1780cb969146422a2ab3b933047absalomon GrColor fColor; 90311bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fXRadius; 90411bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fYRadius; 90511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fInnerXRadius; 90611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fInnerYRadius; 90711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect fDevBounds; 90811bf8b2eae7d1780cb969146422a2ab3b933047absalomon }; 90976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 910cdaa97bf664e0d584187efc125bfff670a064a9absalomon bool fStroked; 911cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix fViewMatrixIfUsingLocalCoords; 91276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 9131b55a963a2374a14bb82eb887bb99ee91680f0ebreed 9141b55a963a2374a14bb82eb887bb99ee91680f0ebreed typedef GrVertexBatch INHERITED; 91576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 91676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 91711bf8b2eae7d1780cb969146422a2ab3b933047absalomon///////////////////////////////////////////////////////////////////////////////////////////////// 9186bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 91911bf8b2eae7d1780cb969146422a2ab3b933047absalomonclass DIEllipseBatch : public GrVertexBatch { 92011bf8b2eae7d1780cb969146422a2ab3b933047absalomonpublic: 92111bf8b2eae7d1780cb969146422a2ab3b933047absalomon DEFINE_BATCH_CLASS_ID 9226bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 92311bf8b2eae7d1780cb969146422a2ab3b933047absalomon static GrDrawBatch* Create(GrColor color, 92411bf8b2eae7d1780cb969146422a2ab3b933047absalomon const SkMatrix& viewMatrix, 92511bf8b2eae7d1780cb969146422a2ab3b933047absalomon const SkRect& ellipse, 92611bf8b2eae7d1780cb969146422a2ab3b933047absalomon const SkStrokeRec& stroke) { 92711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); 92811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar xRadius = SkScalarHalf(ellipse.width()); 92911bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar yRadius = SkScalarHalf(ellipse.height()); 93011bf8b2eae7d1780cb969146422a2ab3b933047absalomon 93111bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkStrokeRec::Style style = stroke.getStyle(); 93211bf8b2eae7d1780cb969146422a2ab3b933047absalomon DIEllipseStyle dieStyle = (SkStrokeRec::kStroke_Style == style) ? 93311bf8b2eae7d1780cb969146422a2ab3b933047absalomon DIEllipseStyle::kStroke : 93411bf8b2eae7d1780cb969146422a2ab3b933047absalomon (SkStrokeRec::kHairline_Style == style) ? 93511bf8b2eae7d1780cb969146422a2ab3b933047absalomon DIEllipseStyle::kHairline : DIEllipseStyle::kFill; 93611bf8b2eae7d1780cb969146422a2ab3b933047absalomon 93711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar innerXRadius = 0; 93811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar innerYRadius = 0; 93911bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (SkStrokeRec::kFill_Style != style && SkStrokeRec::kHairline_Style != style) { 94011bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar strokeWidth = stroke.getWidth(); 94111bf8b2eae7d1780cb969146422a2ab3b933047absalomon 94211bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (SkScalarNearlyZero(strokeWidth)) { 94311bf8b2eae7d1780cb969146422a2ab3b933047absalomon strokeWidth = SK_ScalarHalf; 94411bf8b2eae7d1780cb969146422a2ab3b933047absalomon } else { 94511bf8b2eae7d1780cb969146422a2ab3b933047absalomon strokeWidth *= SK_ScalarHalf; 94611bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 9476bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 94811bf8b2eae7d1780cb969146422a2ab3b933047absalomon // we only handle thick strokes for near-circular ellipses 94911bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (strokeWidth > SK_ScalarHalf && 95011bf8b2eae7d1780cb969146422a2ab3b933047absalomon (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) { 95111bf8b2eae7d1780cb969146422a2ab3b933047absalomon return nullptr; 95211bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 9536bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 95411bf8b2eae7d1780cb969146422a2ab3b933047absalomon // we don't handle it if curvature of the stroke is less than curvature of the ellipse 95511bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius || 95611bf8b2eae7d1780cb969146422a2ab3b933047absalomon strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) { 95711bf8b2eae7d1780cb969146422a2ab3b933047absalomon return nullptr; 95811bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 959fc5b70a8e427ee115868786fa361c2c813ab566bbenjaminwagner 96011bf8b2eae7d1780cb969146422a2ab3b933047absalomon // set inner radius (if needed) 96111bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (SkStrokeRec::kStroke_Style == style) { 96211bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerXRadius = xRadius - strokeWidth; 96311bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerYRadius = yRadius - strokeWidth; 96411bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 965df4f47b8ff6378c4d8f775dcb3169ac7c64f2510benjaminwagner 96611bf8b2eae7d1780cb969146422a2ab3b933047absalomon xRadius += strokeWidth; 96711bf8b2eae7d1780cb969146422a2ab3b933047absalomon yRadius += strokeWidth; 96811bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 96911bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (DIEllipseStyle::kStroke == dieStyle) { 97011bf8b2eae7d1780cb969146422a2ab3b933047absalomon dieStyle = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseStyle ::kStroke : 97111bf8b2eae7d1780cb969146422a2ab3b933047absalomon DIEllipseStyle ::kFill; 9726bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } 9736bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 97411bf8b2eae7d1780cb969146422a2ab3b933047absalomon // This expands the outer rect so that after CTM we end up with a half-pixel border 97511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar a = viewMatrix[SkMatrix::kMScaleX]; 97611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar b = viewMatrix[SkMatrix::kMSkewX]; 97711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar c = viewMatrix[SkMatrix::kMSkewY]; 97811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar d = viewMatrix[SkMatrix::kMScaleY]; 97911bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar geoDx = SK_ScalarHalf / SkScalarSqrt(a*a + c*c); 98011bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar geoDy = SK_ScalarHalf / SkScalarSqrt(b*b + d*d); 98111bf8b2eae7d1780cb969146422a2ab3b933047absalomon 98211bf8b2eae7d1780cb969146422a2ab3b933047absalomon DIEllipseBatch* batch = new DIEllipseBatch(); 98311bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->fGeoData.emplace_back(Geometry { 98411bf8b2eae7d1780cb969146422a2ab3b933047absalomon viewMatrix, 98511bf8b2eae7d1780cb969146422a2ab3b933047absalomon color, 98611bf8b2eae7d1780cb969146422a2ab3b933047absalomon xRadius, 98711bf8b2eae7d1780cb969146422a2ab3b933047absalomon yRadius, 98811bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerXRadius, 98911bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerYRadius, 99011bf8b2eae7d1780cb969146422a2ab3b933047absalomon geoDx, 99111bf8b2eae7d1780cb969146422a2ab3b933047absalomon geoDy, 99211bf8b2eae7d1780cb969146422a2ab3b933047absalomon dieStyle, 99311bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy, 99411bf8b2eae7d1780cb969146422a2ab3b933047absalomon center.fX + xRadius + geoDx, center.fY + yRadius + geoDy) 99511bf8b2eae7d1780cb969146422a2ab3b933047absalomon }); 99611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect devBounds = batch->fGeoData.back().fBounds; 99711bf8b2eae7d1780cb969146422a2ab3b933047absalomon viewMatrix.mapRect(&devBounds); 99811bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->setBounds(devBounds); 99911bf8b2eae7d1780cb969146422a2ab3b933047absalomon return batch; 100076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 100176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 100236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "DIEllipseBatch"; } 100376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 10049d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary void computePipelineOptimizations(GrInitInvariantOutput* color, 1005ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrInitInvariantOutput* coverage, 1006ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrBatchToXPOverrides* overrides) const override { 100776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 1008ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas color->setKnownFourComponents(fGeoData[0].fColor); 1009ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas coverage->setUnknownSingleComponent(); 101076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 101176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1012e46f9feb44780a6269c6dcfe993f4215427fd98ebsalomonprivate: 1013e46f9feb44780a6269c6dcfe993f4215427fd98ebsalomon 101411bf8b2eae7d1780cb969146422a2ab3b933047absalomon DIEllipseBatch() : INHERITED(ClassID()) {} 101511bf8b2eae7d1780cb969146422a2ab3b933047absalomon 1016ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 1017cdaa97bf664e0d584187efc125bfff670a064a9absalomon // Handle any overrides that affect our GP. 1018ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas overrides.getOverrideColorIfSet(&fGeoData[0].fColor); 1019cdaa97bf664e0d584187efc125bfff670a064a9absalomon fUsesLocalCoords = overrides.readsLocalCoords(); 102076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 102176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1022144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt void onPrepareDraws(Target* target) const override { 102376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 1024cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkAutoTUnref<GrGeometryProcessor> gp(new DIEllipseGeometryProcessor(this->viewMatrix(), 1025cdaa97bf664e0d584187efc125bfff670a064a9absalomon this->style())); 102676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 102776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 102876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 102919e0058a650a9e4dc9c35ed26c5e91916bcc0601joshualitt SkASSERT(vertexStride == sizeof(DIEllipseVertex)); 1030b5238a7571c243ba4a154a62575570c3078b3741bsalomon QuadHelper helper; 1031b5238a7571c243ba4a154a62575570c3078b3741bsalomon DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>( 10327539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon helper.init(target, vertexStride, instanceCount)); 1033b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts) { 10344b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 10354b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 10364b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 103776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 1038144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt const Geometry& geom = fGeoData[i]; 103976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1040bb2ff94e223014403f775c3532a25cc25b00c949brianosman GrColor color = geom.fColor; 1041b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar xRadius = geom.fXRadius; 1042b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar yRadius = geom.fYRadius; 104376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1044b5238a7571c243ba4a154a62575570c3078b3741bsalomon const SkRect& bounds = geom.fBounds; 104576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 104676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // This adjusts the "radius" to include the half-pixel border 104780ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar offsetDx = geom.fGeoDx / xRadius; 104880ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar offsetDy = geom.fGeoDy / yRadius; 104976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 105080ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar innerRatioX = xRadius / geom.fInnerXRadius; 105180ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar innerRatioY = yRadius / geom.fInnerYRadius; 105276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 105376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); 1054bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[0].fColor = color; 105576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy); 105676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, -innerRatioY - offsetDy); 105776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 105876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); 1059bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[1].fColor = color; 106076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, 1.0f + offsetDy); 106176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, innerRatioY + offsetDy); 106276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 106376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); 1064bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[2].fColor = color; 106576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy); 106676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerRatioY + offsetDy); 106776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 106876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); 1069bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts[3].fColor = color; 107076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy); 107176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy); 107276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1073b5238a7571c243ba4a154a62575570c3078b3741bsalomon verts += kVerticesPerQuad; 107476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 1075342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon helper.recordDraw(target, gp); 107676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 10779d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 1078cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 1079abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon DIEllipseBatch* that = t->cast<DIEllipseBatch>(); 1080abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 1081abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon that->bounds(), caps)) { 10828cab9a7685e872427e6f0388f149575a9b6016eejoshualitt return false; 10838cab9a7685e872427e6f0388f149575a9b6016eejoshualitt } 10848cab9a7685e872427e6f0388f149575a9b6016eejoshualitt 1085cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (this->style() != that->style()) { 108676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 108776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 108876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1089d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt // TODO rewrite to allow positioning on CPU 1090d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 109176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 109276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 109376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1094cdaa97bf664e0d584187efc125bfff670a064a9absalomon fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 109599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 109676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 109776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 109876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 109976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 1100cdaa97bf664e0d584187efc125bfff670a064a9absalomon DIEllipseStyle style() const { return fGeoData[0].fStyle; } 110176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 110211bf8b2eae7d1780cb969146422a2ab3b933047absalomon struct Geometry { 110311bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkMatrix fViewMatrix; 110411bf8b2eae7d1780cb969146422a2ab3b933047absalomon GrColor fColor; 110511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fXRadius; 110611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fYRadius; 110711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fInnerXRadius; 110811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fInnerYRadius; 110911bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fGeoDx; 111011bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fGeoDy; 111111bf8b2eae7d1780cb969146422a2ab3b933047absalomon DIEllipseStyle fStyle; 111211bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect fBounds; 111311bf8b2eae7d1780cb969146422a2ab3b933047absalomon }; 111411bf8b2eae7d1780cb969146422a2ab3b933047absalomon 1115cdaa97bf664e0d584187efc125bfff670a064a9absalomon bool fUsesLocalCoords; 111676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 11171b55a963a2374a14bb82eb887bb99ee91680f0ebreed 11181b55a963a2374a14bb82eb887bb99ee91680f0ebreed typedef GrVertexBatch INHERITED; 111976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 1120f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1121f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 1122f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1123f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.orgstatic const uint16_t gRRectIndices[] = { 1124f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // corners 1125f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 0, 1, 5, 0, 5, 4, 1126f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2, 3, 7, 2, 7, 6, 1127f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 8, 9, 13, 8, 13, 12, 1128f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 10, 11, 15, 10, 15, 14, 11292cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 1130f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // edges 1131f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1, 2, 6, 1, 6, 5, 1132f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 4, 5, 9, 4, 9, 8, 1133f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 6, 7, 11, 6, 11, 10, 1134f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 9, 10, 14, 9, 14, 13, 11352cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 1136f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // center 1137f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // we place this at the end so that we can ignore these indices when rendering stroke-only 1138f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 5, 6, 10, 5, 10, 9 1139f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org}; 1140f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 11415ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualittstatic const int kIndicesPerStrokeRRect = SK_ARRAY_COUNT(gRRectIndices) - 6; 11425ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualittstatic const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices); 11435ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualittstatic const int kVertsPerRRect = 16; 11445ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualittstatic const int kNumRRectsInIndexBuffer = 256; 11455ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualitt 1146ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomonGR_DECLARE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey); 1147ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomonGR_DECLARE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey); 1148397536cabe12a9936659870dd220c869789424bacdaltonstatic const GrBuffer* ref_rrect_index_buffer(bool strokeOnly, 1149397536cabe12a9936659870dd220c869789424bacdalton GrResourceProvider* resourceProvider) { 1150ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon GR_DEFINE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey); 1151ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey); 1152ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon if (strokeOnly) { 1153eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon return resourceProvider->findOrCreateInstancedIndexBuffer( 1154ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon gRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer, kVertsPerRRect, 1155ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon gStrokeRRectOnlyIndexBufferKey); 1156ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } else { 1157eae6200acbec2255ac00ab363ffbe16758ec9076bsalomon return resourceProvider->findOrCreateInstancedIndexBuffer( 1158ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon gRRectIndices, kIndicesPerRRect, kNumRRectsInIndexBuffer, kVertsPerRRect, 1159ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon gRRectOnlyIndexBufferKey); 1160ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 1161ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } 1162ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon} 1163ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 116476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt/////////////////////////////////////////////////////////////////////////////////////////////////// 116576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1166abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonclass RRectCircleRendererBatch : public GrVertexBatch { 116776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittpublic: 11681b55a963a2374a14bb82eb887bb99ee91680f0ebreed DEFINE_BATCH_CLASS_ID 11691b55a963a2374a14bb82eb887bb99ee91680f0ebreed 117011bf8b2eae7d1780cb969146422a2ab3b933047absalomon // A devStrokeWidth <= 0 indicates a fill only. If devStrokeWidth > 0 then strokeOnly indicates 117111bf8b2eae7d1780cb969146422a2ab3b933047absalomon // whether the rrect is only stroked or stroked and filled. 117211bf8b2eae7d1780cb969146422a2ab3b933047absalomon RRectCircleRendererBatch(GrColor color, const SkMatrix& viewMatrix, const SkRect& devRect, 117311bf8b2eae7d1780cb969146422a2ab3b933047absalomon float devRadius, float devStrokeWidth, bool strokeOnly) 117411bf8b2eae7d1780cb969146422a2ab3b933047absalomon : INHERITED(ClassID()) 117511bf8b2eae7d1780cb969146422a2ab3b933047absalomon , fViewMatrixIfUsingLocalCoords(viewMatrix) { 117611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect bounds = devRect; 117711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkASSERT(!(devStrokeWidth <= 0 && strokeOnly)); 117811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar innerRadius = 0.0f; 117911bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar outerRadius = devRadius; 118011bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar halfWidth = 0; 118111bf8b2eae7d1780cb969146422a2ab3b933047absalomon fStroked = false; 118211bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (devStrokeWidth > 0) { 118311bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (SkScalarNearlyZero(devStrokeWidth)) { 118411bf8b2eae7d1780cb969146422a2ab3b933047absalomon halfWidth = SK_ScalarHalf; 118511bf8b2eae7d1780cb969146422a2ab3b933047absalomon } else { 118611bf8b2eae7d1780cb969146422a2ab3b933047absalomon halfWidth = SkScalarHalf(devStrokeWidth); 118711bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 118876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 118911bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (strokeOnly) { 119011bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerRadius = devRadius - halfWidth; 119111bf8b2eae7d1780cb969146422a2ab3b933047absalomon fStroked = innerRadius >= 0; 119211bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 119311bf8b2eae7d1780cb969146422a2ab3b933047absalomon outerRadius += halfWidth; 119411bf8b2eae7d1780cb969146422a2ab3b933047absalomon bounds.outset(halfWidth, halfWidth); 119511bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 1196cdaa97bf664e0d584187efc125bfff670a064a9absalomon 119711bf8b2eae7d1780cb969146422a2ab3b933047absalomon // The radii are outset for two reasons. First, it allows the shader to simply perform 119811bf8b2eae7d1780cb969146422a2ab3b933047absalomon // simpler computation because the computed alpha is zero, rather than 50%, at the radius. 119911bf8b2eae7d1780cb969146422a2ab3b933047absalomon // Second, the outer radius is used to compute the verts of the bounding box that is 120011bf8b2eae7d1780cb969146422a2ab3b933047absalomon // rendered and the outset ensures the box will cover all partially covered by the rrect 120111bf8b2eae7d1780cb969146422a2ab3b933047absalomon // corners. 120211bf8b2eae7d1780cb969146422a2ab3b933047absalomon outerRadius += SK_ScalarHalf; 120311bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerRadius -= SK_ScalarHalf; 120411bf8b2eae7d1780cb969146422a2ab3b933047absalomon 120511bf8b2eae7d1780cb969146422a2ab3b933047absalomon // Expand the rect so all the pixels will be captured. 120611bf8b2eae7d1780cb969146422a2ab3b933047absalomon bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 120711bf8b2eae7d1780cb969146422a2ab3b933047absalomon 120811bf8b2eae7d1780cb969146422a2ab3b933047absalomon fGeoData.emplace_back(Geometry { color, innerRadius, outerRadius, bounds }); 120911bf8b2eae7d1780cb969146422a2ab3b933047absalomon this->setBounds(bounds); 121076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 121176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 121236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "RRectCircleBatch"; } 121376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 12149d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary void computePipelineOptimizations(GrInitInvariantOutput* color, 1215ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrInitInvariantOutput* coverage, 1216ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrBatchToXPOverrides* overrides) const override { 121776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 1218ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas color->setKnownFourComponents(fGeoData[0].fColor); 1219ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas coverage->setUnknownSingleComponent(); 122076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 122176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1222e46f9feb44780a6269c6dcfe993f4215427fd98ebsalomonprivate: 1223ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 1224cdaa97bf664e0d584187efc125bfff670a064a9absalomon // Handle any overrides that affect our GP. 1225ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas overrides.getOverrideColorIfSet(&fGeoData[0].fColor); 1226cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!overrides.readsLocalCoords()) { 1227cdaa97bf664e0d584187efc125bfff670a064a9absalomon fViewMatrixIfUsingLocalCoords.reset(); 1228cdaa97bf664e0d584187efc125bfff670a064a9absalomon } 122976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 123076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1231144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt void onPrepareDraws(Target* target) const override { 1232cdaa97bf664e0d584187efc125bfff670a064a9absalomon // Invert the view matrix as a local matrix (if any other processors require coords). 1233cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix localMatrix; 1234cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { 123576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return; 123676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 123776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 123876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 1239cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkAutoTUnref<GrGeometryProcessor> gp(new CircleGeometryProcessor(fStroked, localMatrix)); 124076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 124176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 124276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 124376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(vertexStride == sizeof(CircleVertex)); 124476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1245b5238a7571c243ba4a154a62575570c3078b3741bsalomon // drop out the middle quad if we're stroked 1246cdaa97bf664e0d584187efc125bfff670a064a9absalomon int indicesPerInstance = fStroked ? kIndicesPerStrokeRRect : kIndicesPerRRect; 1247397536cabe12a9936659870dd220c869789424bacdalton SkAutoTUnref<const GrBuffer> indexBuffer( 1248cdaa97bf664e0d584187efc125bfff670a064a9absalomon ref_rrect_index_buffer(fStroked, target->resourceProvider())); 124976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1250b5238a7571c243ba4a154a62575570c3078b3741bsalomon InstancedHelper helper; 12517539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(target, 1252b5238a7571c243ba4a154a62575570c3078b3741bsalomon kTriangles_GrPrimitiveType, vertexStride, indexBuffer, kVertsPerRRect, 1253b5238a7571c243ba4a154a62575570c3078b3741bsalomon indicesPerInstance, instanceCount)); 1254b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts || !indexBuffer) { 12554b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate vertices\n"); 12564b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 12574b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 12584b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 125976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 1260144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt const Geometry& args = fGeoData[i]; 126176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1262bb2ff94e223014403f775c3532a25cc25b00c949brianosman GrColor color = args.fColor; 126376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar outerRadius = args.fOuterRadius; 126476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1265bc227140ffea6eb15e2e8b147eb6d8ec6228d95aegdaniel const SkRect& bounds = args.fDevBounds; 126676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 126776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yCoords[4] = { 126876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fTop, 126976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fTop + outerRadius, 127076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fBottom - outerRadius, 127176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fBottom 127276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 127376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 127476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yOuterRadii[4] = {-1, 0, 0, 1 }; 127576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // The inner radius in the vertex data must be specified in normalized space. 127676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar innerRadius = args.fInnerRadius / args.fOuterRadius; 127776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < 4; ++i) { 127876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); 1279bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts->fColor = color; 128076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(-1, yOuterRadii[i]); 128176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadius = outerRadius; 128276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadius = innerRadius; 128376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 128476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 128576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[i]); 1286bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts->fColor = color; 128776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(0, yOuterRadii[i]); 128876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadius = outerRadius; 128976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadius = innerRadius; 129076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 129176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 129276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords[i]); 1293bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts->fColor = color; 129476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(0, yOuterRadii[i]); 129576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadius = outerRadius; 129676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadius = innerRadius; 129776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 129876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 129976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); 1300bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts->fColor = color; 130176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(1, yOuterRadii[i]); 130276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadius = outerRadius; 130376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadius = innerRadius; 130476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 130576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 130676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 130776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1308342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon helper.recordDraw(target, gp); 130976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 131076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1311cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 1312abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>(); 1313abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 1314abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon that->bounds(), caps)) { 13158cab9a7685e872427e6f0388f149575a9b6016eejoshualitt return false; 13168cab9a7685e872427e6f0388f149575a9b6016eejoshualitt } 13178cab9a7685e872427e6f0388f149575a9b6016eejoshualitt 1318cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (fStroked != that->fStroked) { 131976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 132076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 132176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1322cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { 132376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 132476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 132576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1326cdaa97bf664e0d584187efc125bfff670a064a9absalomon fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 132799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 132876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 132976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 133076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 133111bf8b2eae7d1780cb969146422a2ab3b933047absalomon struct Geometry { 133211bf8b2eae7d1780cb969146422a2ab3b933047absalomon GrColor fColor; 133311bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fInnerRadius; 133411bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fOuterRadius; 133511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect fDevBounds; 133611bf8b2eae7d1780cb969146422a2ab3b933047absalomon }; 133711bf8b2eae7d1780cb969146422a2ab3b933047absalomon 1338cdaa97bf664e0d584187efc125bfff670a064a9absalomon bool fStroked; 1339cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix fViewMatrixIfUsingLocalCoords; 134076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 13411b55a963a2374a14bb82eb887bb99ee91680f0ebreed 13421b55a963a2374a14bb82eb887bb99ee91680f0ebreed typedef GrVertexBatch INHERITED; 134376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 134476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1345abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonclass RRectEllipseRendererBatch : public GrVertexBatch { 134676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittpublic: 13471b55a963a2374a14bb82eb887bb99ee91680f0ebreed DEFINE_BATCH_CLASS_ID 13481b55a963a2374a14bb82eb887bb99ee91680f0ebreed 134911bf8b2eae7d1780cb969146422a2ab3b933047absalomon // If devStrokeWidths values are <= 0 indicates then fill only. Otherwise, strokeOnly indicates 135011bf8b2eae7d1780cb969146422a2ab3b933047absalomon // whether the rrect is only stroked or stroked and filled. 135111bf8b2eae7d1780cb969146422a2ab3b933047absalomon static GrDrawBatch* Create(GrColor color, const SkMatrix& viewMatrix, const SkRect& devRect, 135211bf8b2eae7d1780cb969146422a2ab3b933047absalomon float devXRadius, float devYRadius, SkVector devStrokeWidths, 135311bf8b2eae7d1780cb969146422a2ab3b933047absalomon bool strokeOnly) { 135411bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkASSERT(devXRadius > 0.5); 135511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkASSERT(devYRadius > 0.5); 135611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkASSERT((devStrokeWidths.fX > 0) == (devStrokeWidths.fY > 0)); 135711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkASSERT(!(strokeOnly && devStrokeWidths.fX <= 0)); 135811bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar innerXRadius = 0.0f; 135911bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar innerYRadius = 0.0f; 136011bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect bounds = devRect; 136111bf8b2eae7d1780cb969146422a2ab3b933047absalomon bool stroked = false; 136211bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (devStrokeWidths.fX > 0) { 136311bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (SkScalarNearlyZero(devStrokeWidths.length())) { 136411bf8b2eae7d1780cb969146422a2ab3b933047absalomon devStrokeWidths.set(SK_ScalarHalf, SK_ScalarHalf); 136511bf8b2eae7d1780cb969146422a2ab3b933047absalomon } else { 136611bf8b2eae7d1780cb969146422a2ab3b933047absalomon devStrokeWidths.scale(SK_ScalarHalf); 136711bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 136811bf8b2eae7d1780cb969146422a2ab3b933047absalomon 136911bf8b2eae7d1780cb969146422a2ab3b933047absalomon // we only handle thick strokes for near-circular ellipses 137011bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (devStrokeWidths.length() > SK_ScalarHalf && 137111bf8b2eae7d1780cb969146422a2ab3b933047absalomon (SK_ScalarHalf*devXRadius > devYRadius || SK_ScalarHalf*devYRadius > devXRadius)) { 137211bf8b2eae7d1780cb969146422a2ab3b933047absalomon return nullptr; 137311bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 137411bf8b2eae7d1780cb969146422a2ab3b933047absalomon 137511bf8b2eae7d1780cb969146422a2ab3b933047absalomon // we don't handle it if curvature of the stroke is less than curvature of the ellipse 137611bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (devStrokeWidths.fX*(devYRadius*devYRadius) < 137711bf8b2eae7d1780cb969146422a2ab3b933047absalomon (devStrokeWidths.fY*devStrokeWidths.fY)*devXRadius) { 137811bf8b2eae7d1780cb969146422a2ab3b933047absalomon return nullptr; 137911bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 138011bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (devStrokeWidths.fY*(devXRadius*devXRadius) < 138111bf8b2eae7d1780cb969146422a2ab3b933047absalomon (devStrokeWidths.fX*devStrokeWidths.fX)*devYRadius) { 138211bf8b2eae7d1780cb969146422a2ab3b933047absalomon return nullptr; 138311bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 13847f06c6947a3bef78dc57b9252779567c33604c90bsalomon 138511bf8b2eae7d1780cb969146422a2ab3b933047absalomon // this is legit only if scale & translation (which should be the case at the moment) 138611bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (strokeOnly) { 138711bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerXRadius = devXRadius - devStrokeWidths.fX; 138811bf8b2eae7d1780cb969146422a2ab3b933047absalomon innerYRadius = devYRadius - devStrokeWidths.fY; 138911bf8b2eae7d1780cb969146422a2ab3b933047absalomon stroked = (innerXRadius >= 0 && innerYRadius >= 0); 139011bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 139111bf8b2eae7d1780cb969146422a2ab3b933047absalomon 139211bf8b2eae7d1780cb969146422a2ab3b933047absalomon devXRadius += devStrokeWidths.fX; 139311bf8b2eae7d1780cb969146422a2ab3b933047absalomon devYRadius += devStrokeWidths.fY; 139411bf8b2eae7d1780cb969146422a2ab3b933047absalomon bounds.outset(devStrokeWidths.fX, devStrokeWidths.fY); 139511bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 139611bf8b2eae7d1780cb969146422a2ab3b933047absalomon 139711bf8b2eae7d1780cb969146422a2ab3b933047absalomon // Expand the rect so all the pixels will be captured. 139811bf8b2eae7d1780cb969146422a2ab3b933047absalomon bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 139911bf8b2eae7d1780cb969146422a2ab3b933047absalomon 140011bf8b2eae7d1780cb969146422a2ab3b933047absalomon RRectEllipseRendererBatch* batch = new RRectEllipseRendererBatch(); 140111bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->fStroked = stroked; 140211bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->fViewMatrixIfUsingLocalCoords = viewMatrix; 140311bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->fGeoData.emplace_back( 140411bf8b2eae7d1780cb969146422a2ab3b933047absalomon Geometry {color, devXRadius, devYRadius, innerXRadius, innerYRadius, bounds}); 140511bf8b2eae7d1780cb969146422a2ab3b933047absalomon batch->setBounds(bounds); 140611bf8b2eae7d1780cb969146422a2ab3b933047absalomon return batch; 140776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 140876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 140936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "RRectEllipseRendererBatch"; } 141076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 14119d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary void computePipelineOptimizations(GrInitInvariantOutput* color, 1412ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrInitInvariantOutput* coverage, 1413ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas GrBatchToXPOverrides* overrides) const override { 141476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 1415ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas color->setKnownFourComponents(fGeoData[0].fColor); 1416ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas coverage->setUnknownSingleComponent(); 141776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 141876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1419e46f9feb44780a6269c6dcfe993f4215427fd98ebsalomonprivate: 142011bf8b2eae7d1780cb969146422a2ab3b933047absalomon RRectEllipseRendererBatch() : INHERITED(ClassID()) {} 142111bf8b2eae7d1780cb969146422a2ab3b933047absalomon 1422ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas void initBatchTracker(const GrXPOverridesForBatch& overrides) override { 1423cdaa97bf664e0d584187efc125bfff670a064a9absalomon // Handle overrides that affect our GP. 1424ff2103200bad7abcf8929ae22ac78a9f4f725142ethannicholas overrides.getOverrideColorIfSet(&fGeoData[0].fColor); 1425cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!overrides.readsLocalCoords()) { 1426cdaa97bf664e0d584187efc125bfff670a064a9absalomon fViewMatrixIfUsingLocalCoords.reset(); 1427cdaa97bf664e0d584187efc125bfff670a064a9absalomon } 142876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 142976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1430144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt void onPrepareDraws(Target* target) const override { 1431cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix localMatrix; 1432cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!fViewMatrixIfUsingLocalCoords.invert(&localMatrix)) { 143376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return; 143476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 143576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 143676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 1437cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkAutoTUnref<GrGeometryProcessor> gp(new EllipseGeometryProcessor(fStroked, localMatrix)); 143876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 143976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 144076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 144176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(vertexStride == sizeof(EllipseVertex)); 144276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1443b5238a7571c243ba4a154a62575570c3078b3741bsalomon // drop out the middle quad if we're stroked 1444cdaa97bf664e0d584187efc125bfff670a064a9absalomon int indicesPerInstance = fStroked ? kIndicesPerStrokeRRect : kIndicesPerRRect; 1445397536cabe12a9936659870dd220c869789424bacdalton SkAutoTUnref<const GrBuffer> indexBuffer( 1446cdaa97bf664e0d584187efc125bfff670a064a9absalomon ref_rrect_index_buffer(fStroked, target->resourceProvider())); 144776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1448b5238a7571c243ba4a154a62575570c3078b3741bsalomon InstancedHelper helper; 1449b5238a7571c243ba4a154a62575570c3078b3741bsalomon EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( 14507539856c1b9cbb1886a6a498cc534b77fc83ddb2bsalomon helper.init(target, kTriangles_GrPrimitiveType, vertexStride, indexBuffer, 1451b5238a7571c243ba4a154a62575570c3078b3741bsalomon kVertsPerRRect, indicesPerInstance, instanceCount)); 1452b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts || !indexBuffer) { 14534b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate vertices\n"); 14544b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 14554b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 14564b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 145776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 1458144c3c8b7ff3ebc389b41211f3388fb24a7ff0c2joshualitt const Geometry& args = fGeoData[i]; 145976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1460bb2ff94e223014403f775c3532a25cc25b00c949brianosman GrColor color = args.fColor; 1461bb2ff94e223014403f775c3532a25cc25b00c949brianosman 146276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Compute the reciprocals of the radii here to save time in the shader 146376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar xRadRecip = SkScalarInvert(args.fXRadius); 146476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yRadRecip = SkScalarInvert(args.fYRadius); 146576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius); 146676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius); 146776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 146876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Extend the radii out half a pixel to antialias. 146976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar xOuterRadius = args.fXRadius + SK_ScalarHalf; 147076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yOuterRadius = args.fYRadius + SK_ScalarHalf; 147176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1472bc227140ffea6eb15e2e8b147eb6d8ec6228d95aegdaniel const SkRect& bounds = args.fDevBounds; 147376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 147476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yCoords[4] = { 147576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fTop, 147676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fTop + yOuterRadius, 147776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fBottom - yOuterRadius, 147876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fBottom 147976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 148076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yOuterOffsets[4] = { 148176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt yOuterRadius, 148276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SK_ScalarNearlyZero, // we're using inversesqrt() in shader, so can't be exactly 0 148376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SK_ScalarNearlyZero, 148476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt yOuterRadius 148576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 148676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 148776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < 4; ++i) { 148876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); 1489bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts->fColor = color; 149076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); 149176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 149276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 149376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 149476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 149576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fLeft + xOuterRadius, yCoords[i]); 1496bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts->fColor = color; 149776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i]); 149876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 149976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 150076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 150176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 150276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fRight - xOuterRadius, yCoords[i]); 1503bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts->fColor = color; 150476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i]); 150576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 150676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 150776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 150876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 150976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); 1510bb2ff94e223014403f775c3532a25cc25b00c949brianosman verts->fColor = color; 151176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); 151276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 151376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 151476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 151576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 151676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 1517342bfc25de5b0452b1551bf9db4bf45eac7718b2bsalomon helper.recordDraw(target, gp); 151876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 151976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1520cb02b38b2c48bfde333ce3c699dd0451e2d867fabsalomon bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { 1521abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon RRectEllipseRendererBatch* that = t->cast<RRectEllipseRendererBatch>(); 1522abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon 1523abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(), 1524abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon that->bounds(), caps)) { 15258cab9a7685e872427e6f0388f149575a9b6016eejoshualitt return false; 15268cab9a7685e872427e6f0388f149575a9b6016eejoshualitt } 15278cab9a7685e872427e6f0388f149575a9b6016eejoshualitt 1528cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (fStroked != that->fStroked) { 152976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 153076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 153176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1532cdaa97bf664e0d584187efc125bfff670a064a9absalomon if (!fViewMatrixIfUsingLocalCoords.cheapEqualTo(that->fViewMatrixIfUsingLocalCoords)) { 153376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 153476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 153576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1536cdaa97bf664e0d584187efc125bfff670a064a9absalomon fGeoData.push_back_n(that->fGeoData.count(), that->fGeoData.begin()); 153799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 153876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 153976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 154076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 154111bf8b2eae7d1780cb969146422a2ab3b933047absalomon struct Geometry { 154211bf8b2eae7d1780cb969146422a2ab3b933047absalomon GrColor fColor; 154311bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fXRadius; 154411bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fYRadius; 154511bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fInnerXRadius; 154611bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkScalar fInnerYRadius; 154711bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkRect fDevBounds; 154811bf8b2eae7d1780cb969146422a2ab3b933047absalomon }; 154911bf8b2eae7d1780cb969146422a2ab3b933047absalomon 1550cdaa97bf664e0d584187efc125bfff670a064a9absalomon bool fStroked; 1551cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkMatrix fViewMatrixIfUsingLocalCoords; 1552cdaa97bf664e0d584187efc125bfff670a064a9absalomon SkSTArray<1, Geometry, true> fGeoData; 15531b55a963a2374a14bb82eb887bb99ee91680f0ebreed 15541b55a963a2374a14bb82eb887bb99ee91680f0ebreed typedef GrVertexBatch INHERITED; 155576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 155676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1557abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonstatic GrDrawBatch* create_rrect_batch(GrColor color, 1558abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon const SkMatrix& viewMatrix, 1559abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon const SkRRect& rrect, 1560abd30f54b7ff1704a8930c4307ea242d09425d02bsalomon const SkStrokeRec& stroke) { 15613e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkASSERT(viewMatrix.rectStaysRect()); 15623e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkASSERT(rrect.isSimple()); 15633e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkASSERT(!rrect.isOval()); 15643e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 15653e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt // RRect batchs only handle simple, but not too simple, rrects 1566f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // do any matrix crunching before we reset the draw state for device coords 1567f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org const SkRect& rrectBounds = rrect.getBounds(); 1568d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt SkRect bounds; 1569d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt viewMatrix.mapRect(&bounds, rrectBounds); 1570f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1571f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkVector radii = rrect.getSimpleRadii(); 15728059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX + 15738059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMSkewY]*radii.fY); 15748059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX + 15758059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMScaleY]*radii.fY); 15766bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 1577f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkStrokeRec::Style style = stroke.getStyle(); 1578f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 157911bf8b2eae7d1780cb969146422a2ab3b933047absalomon // Do (potentially) anisotropic mapping of stroke. Use -1s to indicate fill-only draws. 158011bf8b2eae7d1780cb969146422a2ab3b933047absalomon SkVector scaledStroke = {-1, -1}; 1581f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkScalar strokeWidth = stroke.getWidth(); 1582f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 15830a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 15840a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org SkStrokeRec::kHairline_Style == style; 15850a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 15860a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 15870a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (hasStroke) { 15880a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (SkStrokeRec::kHairline_Style == style) { 15890a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org scaledStroke.set(1, 1); 15900a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } else { 15918059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] + 15928059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMSkewY])); 15938059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] + 15948059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMScaleY])); 15950a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 15960a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 15970a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // if half of strokewidth is greater than radius, we don't handle that right now 15980a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStroke.fY > yRadius) { 159996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 16000a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 16010a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 16020a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 16030a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // The way the effect interpolates the offset-to-ellipse/circle-center attribute only works on 16040a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner rect of the nine- 16050a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // patch will have fractional coverage. This only matters when the interior is actually filled. 16060a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // We could consider falling back to rect rendering here, since a tiny radius is 16070a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // indistinguishable from a square corner. 16080a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { 160996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1610f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1611f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1612f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // if the corners are circles, use the circle renderer 16130a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius) { 161411bf8b2eae7d1780cb969146422a2ab3b933047absalomon return new RRectCircleRendererBatch(color, viewMatrix, bounds, xRadius, scaledStroke.fX, 161511bf8b2eae7d1780cb969146422a2ab3b933047absalomon isStrokeOnly); 16166bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // otherwise we use the ellipse renderer 1617f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else { 161811bf8b2eae7d1780cb969146422a2ab3b933047absalomon return RRectEllipseRendererBatch::Create(color, viewMatrix, bounds, xRadius, yRadius, 161911bf8b2eae7d1780cb969146422a2ab3b933047absalomon scaledStroke, isStrokeOnly); 1620f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1621f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 16223e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 16233e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 1624b56f92783a5d84347b65f4f01ec3668096649d13robertphillipsGrDrawBatch* GrOvalRenderer::CreateRRectBatch(GrColor color, 16250cc2f85a19d50b45573d71d8c9d6ee1292c9fd3arobertphillips const SkMatrix& viewMatrix, 16260cc2f85a19d50b45573d71d8c9d6ee1292c9fd3arobertphillips const SkRRect& rrect, 16270cc2f85a19d50b45573d71d8c9d6ee1292c9fd3arobertphillips const SkStrokeRec& stroke, 16280cc2f85a19d50b45573d71d8c9d6ee1292c9fd3arobertphillips GrShaderCaps* shaderCaps) { 16290cc2f85a19d50b45573d71d8c9d6ee1292c9fd3arobertphillips if (rrect.isOval()) { 1630b56f92783a5d84347b65f4f01ec3668096649d13robertphillips return CreateOvalBatch(color, viewMatrix, rrect.getBounds(), stroke, shaderCaps); 16313e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt } 16323e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 16330cc2f85a19d50b45573d71d8c9d6ee1292c9fd3arobertphillips if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { 16340cc2f85a19d50b45573d71d8c9d6ee1292c9fd3arobertphillips return nullptr; 16353e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt } 16363e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 16370cc2f85a19d50b45573d71d8c9d6ee1292c9fd3arobertphillips return create_rrect_batch(color, viewMatrix, rrect, stroke); 1638f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org} 16393e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 164011bf8b2eae7d1780cb969146422a2ab3b933047absalomon/////////////////////////////////////////////////////////////////////////////// 164111bf8b2eae7d1780cb969146422a2ab3b933047absalomon 164211bf8b2eae7d1780cb969146422a2ab3b933047absalomonGrDrawBatch* GrOvalRenderer::CreateOvalBatch(GrColor color, 164311bf8b2eae7d1780cb969146422a2ab3b933047absalomon const SkMatrix& viewMatrix, 164411bf8b2eae7d1780cb969146422a2ab3b933047absalomon const SkRect& oval, 164511bf8b2eae7d1780cb969146422a2ab3b933047absalomon const SkStrokeRec& stroke, 164611bf8b2eae7d1780cb969146422a2ab3b933047absalomon GrShaderCaps* shaderCaps) { 164711bf8b2eae7d1780cb969146422a2ab3b933047absalomon // we can draw circles 164811bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(viewMatrix)) { 164911bf8b2eae7d1780cb969146422a2ab3b933047absalomon return new CircleBatch(color, viewMatrix, oval, stroke); 165011bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 165111bf8b2eae7d1780cb969146422a2ab3b933047absalomon 165211bf8b2eae7d1780cb969146422a2ab3b933047absalomon // if we have shader derivative support, render as device-independent 165311bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (shaderCaps->shaderDerivativeSupport()) { 165411bf8b2eae7d1780cb969146422a2ab3b933047absalomon return DIEllipseBatch::Create(color, viewMatrix, oval, stroke); 165511bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 165611bf8b2eae7d1780cb969146422a2ab3b933047absalomon 165711bf8b2eae7d1780cb969146422a2ab3b933047absalomon // otherwise axis-aligned ellipses only 165811bf8b2eae7d1780cb969146422a2ab3b933047absalomon if (viewMatrix.rectStaysRect()) { 165911bf8b2eae7d1780cb969146422a2ab3b933047absalomon return EllipseBatch::Create(color, viewMatrix, oval, stroke); 166011bf8b2eae7d1780cb969146422a2ab3b933047absalomon } 166111bf8b2eae7d1780cb969146422a2ab3b933047absalomon 166211bf8b2eae7d1780cb969146422a2ab3b933047absalomon return nullptr; 166311bf8b2eae7d1780cb969146422a2ab3b933047absalomon} 166411bf8b2eae7d1780cb969146422a2ab3b933047absalomon 166511bf8b2eae7d1780cb969146422a2ab3b933047absalomon/////////////////////////////////////////////////////////////////////////////// 16663e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 16673e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt#ifdef GR_TEST_UTILS 16683e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 1669abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonDRAW_BATCH_TEST_DEFINE(CircleBatch) { 16703e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkMatrix viewMatrix = GrTest::TestMatrix(random); 16713e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color = GrRandomColor(random); 16726c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt SkRect circle = GrTest::TestSquare(random); 167311bf8b2eae7d1780cb969146422a2ab3b933047absalomon return new CircleBatch(color, viewMatrix, circle, GrTest::TestStrokeRec(random)); 16743e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 16753e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 1676abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonDRAW_BATCH_TEST_DEFINE(EllipseBatch) { 16773e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); 16783e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color = GrRandomColor(random); 16796c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt SkRect ellipse = GrTest::TestSquare(random); 168011bf8b2eae7d1780cb969146422a2ab3b933047absalomon return EllipseBatch::Create(color, viewMatrix, ellipse, GrTest::TestStrokeRec(random)); 16813e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 16823e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 1683abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonDRAW_BATCH_TEST_DEFINE(DIEllipseBatch) { 16843e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkMatrix viewMatrix = GrTest::TestMatrix(random); 16853e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color = GrRandomColor(random); 16866c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt SkRect ellipse = GrTest::TestSquare(random); 168711bf8b2eae7d1780cb969146422a2ab3b933047absalomon return DIEllipseBatch::Create(color, viewMatrix, ellipse, GrTest::TestStrokeRec(random)); 16883e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 16893e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 1690abd30f54b7ff1704a8930c4307ea242d09425d02bsalomonDRAW_BATCH_TEST_DEFINE(RRectBatch) { 16913e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); 16923e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color = GrRandomColor(random); 16933e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRRect& rrect = GrTest::TestRRectSimple(random); 169421279c7ada1e47e8bfc6375f67768c8eedffb680joshualitt return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(random)); 16953e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 16963e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 16973e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt#endif 1698