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 1076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt#include "GrBatch.h" 1176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt#include "GrBatchTarget.h" 123e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt#include "GrBatchTest.h" 1381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrDrawTarget.h" 14eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "GrGeometryProcessor.h" 15605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h" 168dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel#include "GrPipelineBuilder.h" 1776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt#include "GrProcessor.h" 18ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon#include "GrResourceProvider.h" 1972e3ae486c66871c2043eac4f08d85d419fbca2absalomon#include "GrVertexBuffer.h" 20f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org#include "SkRRect.h" 2181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "SkStrokeRec.h" 220a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org#include "SkTLazy.h" 230a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org#include "effects/GrRRectEffect.h" 24eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/GrGLProcessor.h" 25eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/GrGLSL.h" 26eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/GrGLGeometryProcessor.h" 27eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/builders/GrGLProgramBuilder.h" 28234d4fba75aac009e34c088037fcd9e244798c40commit-bot@chromium.org 2976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt// TODO(joshualitt) - Break this file up during GrBatch post implementation cleanup 3076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 3181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgnamespace { 325ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualitt// TODO(joshualitt) add per vertex colors 3381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgstruct CircleVertex { 34972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fPos; 35972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fOffset; 3681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkScalar fOuterRadius; 3781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkScalar fInnerRadius; 3881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org}; 3981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 4081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orgstruct EllipseVertex { 41972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fPos; 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; 49972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fOuterOffset; 50972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint fInnerOffset; 515242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org}; 525242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 5381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.orginline bool circle_stays_circle(const SkMatrix& m) { 5481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org return m.isSimilarity(); 5581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org} 5681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 5781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org} 5881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 5990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 6090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 6190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/** 62ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * The output of this effect is a modulation of the input color and coverage for a circle. It 63ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * operates in a space normalized by the circle radius (outer radius in the case of a stroke) 64ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * with origin at the circle center. Two vertex attributes are used: 65ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * vec2f : position in device space of the bounding geometry vertices 66ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * vec4f : (p.xy, outerRad, innerRad) 67ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * p is the position in the normalized space. 68ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * outerRad is the outerRadius in device space. 69ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon * innerRad is the innerRadius in normalized space (ignored if not stroking). 7090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org */ 7190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 72249af15fb82833d2274850c589812b6e69df0033joshualittclass CircleEdgeEffect : public GrGeometryProcessor { 7390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgpublic: 74d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatrix& localMatrix) { 75d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt return SkNEW_ARGS(CircleEdgeEffect, (color, stroke, localMatrix)); 7690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 7790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 7871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inPosition() const { return fInPosition; } 7971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inCircleEdge() const { return fInCircleEdge; } 8088c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt GrColor color() const { return fColor; } 81e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkMatrix& localMatrix() const { return fLocalMatrix; } 8290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org virtual ~CircleEdgeEffect() {} 8390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 8436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "CircleEdge"; } 8590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 8690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org inline bool isStroked() const { return fStroke; } 8790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 88b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt class GLProcessor : public GrGLGeometryProcessor { 8990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org public: 90eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLProcessor(const GrGeometryProcessor&, 919b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker&) 929b98932adaceb7ad0a617ade16616923f6bffe84joshualitt : fColor(GrColor_ILLEGAL) {} 9390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 9436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 952dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt const CircleEdgeEffect& ce = args.fGP.cast<CircleEdgeEffect>(); 969b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 979b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = args.fBT.cast<BatchTracker>(); 982dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 992dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 100abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 101abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(ce); 102abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 10374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag v(kVec4f_GrSLType); 10474077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("CircleEdge", &v); 1052dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt vsBuilder->codeAppendf("%s = %s;", v.vsOut(), ce.inCircleEdge()->fName); 10690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 1079b98932adaceb7ad0a617ade16616923f6bffe84joshualitt // Setup pass through color 1089b98932adaceb7ad0a617ade16616923f6bffe84joshualitt this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, 1099b98932adaceb7ad0a617ade16616923f6bffe84joshualitt &fColorUniform); 1109b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 111abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 112e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt this->setupPosition(pb, gpArgs, ce.inPosition()->fName); 113abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 114abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 11546d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, ce.inPosition()->fName, 116567ff2f6143ecb993dbedede402a43feb71c420atfarina ce.localMatrix(), args.fTransformsIn, args.fTransformsOut); 1174973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 11829bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 11974077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("float d = length(%s.xy);", v.fsIn()); 120ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon fsBuilder->codeAppendf("float edgeAlpha = clamp(%s.z * (1.0 - d), 0.0, 1.0);", v.fsIn()); 1212dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (ce.isStroked()) { 122ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon fsBuilder->codeAppendf("float innerAlpha = clamp(%s.z * (d - %s.w), 0.0, 1.0);", 123ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon v.fsIn(), v.fsIn()); 12474077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("edgeAlpha *= innerAlpha;"); 12590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 1260a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org 1272dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); 12890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 12990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 13046d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static void GenKey(const GrGeometryProcessor& gp, 1319b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 132cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 133b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 1349b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = bt.cast<BatchTracker>(); 135e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const CircleEdgeEffect& ce = gp.cast<CircleEdgeEffect>(); 136e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt uint16_t key = ce.isStroked() ? 0x1 : 0x0; 137e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt key |= local.fUsesLocalCoords && ce.localMatrix().hasPerspective() ? 0x2 : 0x0; 1388fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key << 16 | local.fInputColorType); 13990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 14090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 1419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt virtual void setData(const GrGLProgramDataManager& pdman, 1429b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& gp, 14336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 1449b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = bt.cast<BatchTracker>(); 1459b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 1469b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 1479b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 1489b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 1499b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 1509b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 1519b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 15290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 153e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt void setTransformData(const GrPrimitiveProcessor& primProc, 154e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const GrGLProgramDataManager& pdman, 155e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt int index, 156e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkTArray<const GrCoordTransform*, true>& transforms) override { 157e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt this->setTransformDataHelper<CircleEdgeEffect>(primProc, pdman, index, transforms); 158e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt } 159e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt 16090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org private: 1619b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 1629b98932adaceb7ad0a617ade16616923f6bffe84joshualitt UniformHandle fColorUniform; 163249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 16490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org }; 16590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 166eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt virtual void getGLProcessorKey(const GrBatchTracker& bt, 167cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps& caps, 16836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrProcessorKeyBuilder* b) const override { 169eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLProcessor::GenKey(*this, bt, caps, b); 170eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 171eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 172abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, 173cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&) const override { 174eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GLProcessor, (*this, bt)); 175eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 17690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 17736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { 1789b98932adaceb7ad0a617ade16616923f6bffe84joshualitt BatchTracker* local = bt->cast<BatchTracker>(); 1799b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); 180290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 1819b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 1829b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 18390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgprivate: 184d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt CircleEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix) 185e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt : fColor(color) 186e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt , fLocalMatrix(localMatrix) { 187eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<CircleEdgeEffect>(); 188c375b0b5c5c03d381111bf7bff12507d5ed24769senorblanco fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType, 189c375b0b5c5c03d381111bf7bff12507d5ed24769senorblanco kHigh_GrSLPrecision)); 19071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInCircleEdge = &this->addVertexAttrib(Attribute("inCircleEdge", 1912dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt kVec4f_GrVertexAttribType)); 19290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org fStroke = stroke; 19390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 19490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 1959b98932adaceb7ad0a617ade16616923f6bffe84joshualitt struct BatchTracker { 1969b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 1979b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 198290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 1999b98932adaceb7ad0a617ade16616923f6bffe84joshualitt }; 2009b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 20188c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt GrColor fColor; 202e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt SkMatrix fLocalMatrix; 20371c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInPosition; 20471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInCircleEdge; 20590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org bool fStroke; 20690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 207b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 20890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 209249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGeometryProcessor INHERITED; 21090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org}; 21190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 212b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(CircleEdgeEffect); 21390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 214b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, 215b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext* context, 216b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 217b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 2188059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt return CircleEdgeEffect::Create(GrRandomColor(random), 2198059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt random->nextBool(), 2204eaf9cef5a76098f78efac30beb966ac833d32c2joshualitt GrTest::TestMatrix(random)); 22190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org} 22290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 22390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 22490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 22590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/** 22690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org * The output of this effect is a modulation of the input color and coverage for an axis-aligned 2278be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com * ellipse, specified as a 2D offset from center, and the reciprocals of the outer and inner radii, 2288be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com * in both x and y directions. 2298be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com * 2306bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org * We are using an implicit function of x^2/a^2 + y^2/b^2 - 1 = 0. 23190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org */ 23290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 233249af15fb82833d2274850c589812b6e69df0033joshualittclass EllipseEdgeEffect : public GrGeometryProcessor { 23490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgpublic: 235d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt static GrGeometryProcessor* Create(GrColor color, bool stroke, const SkMatrix& localMatrix) { 236d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke, localMatrix)); 23790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 23890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 23990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org virtual ~EllipseEdgeEffect() {} 24090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 24136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "EllipseEdge"; } 2422dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 24371c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inPosition() const { return fInPosition; } 24471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inEllipseOffset() const { return fInEllipseOffset; } 24571c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inEllipseRadii() const { return fInEllipseRadii; } 24688c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt GrColor color() const { return fColor; } 247e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkMatrix& localMatrix() const { return fLocalMatrix; } 248249af15fb82833d2274850c589812b6e69df0033joshualitt 24990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org inline bool isStroked() const { return fStroke; } 25090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 251b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt class GLProcessor : public GrGLGeometryProcessor { 25290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org public: 253eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLProcessor(const GrGeometryProcessor&, 2549b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker&) 2559b98932adaceb7ad0a617ade16616923f6bffe84joshualitt : fColor(GrColor_ILLEGAL) {} 25690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 25736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 2582dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt const EllipseEdgeEffect& ee = args.fGP.cast<EllipseEdgeEffect>(); 2599b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 2609b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = args.fBT.cast<BatchTracker>(); 2612dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 26290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 263abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 264abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(ee); 265abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 26674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag ellipseOffsets(kVec2f_GrSLType); 26774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("EllipseOffsets", &ellipseOffsets); 26874077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt vsBuilder->codeAppendf("%s = %s;", ellipseOffsets.vsOut(), 2692dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt ee.inEllipseOffset()->fName); 27090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 27174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag ellipseRadii(kVec4f_GrSLType); 27274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("EllipseRadii", &ellipseRadii); 27374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt vsBuilder->codeAppendf("%s = %s;", ellipseRadii.vsOut(), 2742dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt ee.inEllipseRadii()->fName); 2752dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 2769b98932adaceb7ad0a617ade16616923f6bffe84joshualitt // Setup pass through color 2779b98932adaceb7ad0a617ade16616923f6bffe84joshualitt this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, 2789b98932adaceb7ad0a617ade16616923f6bffe84joshualitt &fColorUniform); 2799b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 280abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 281e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt this->setupPosition(pb, gpArgs, ee.inPosition()->fName); 282abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 283abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 28446d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, ee.inPosition()->fName, 285abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt ee.localMatrix(), args.fTransformsIn, args.fTransformsOut); 2864973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 2878be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com // for outer curve 28829bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 28974077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(), 29074077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt ellipseRadii.fsIn()); 29174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;"); 29274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn()); 29374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float grad_dot = dot(grad, grad);"); 29474077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt 2951b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org // avoid calling inversesqrt on zero. 29674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);"); 29774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);"); 29874077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);"); 299f58d8540a42e5138e7cdb1dd1e0b4de0fa3c4a10jvanverth@google.com 3006bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // for inner curve 3012dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (ee.isStroked()) { 30274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("scaledOffset = %s*%s.zw;", 30374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt ellipseOffsets.fsIn(), ellipseRadii.fsIn()); 30474077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;"); 30574077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;", 30674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt ellipseRadii.fsIn()); 30774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));"); 30874077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);"); 30990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 31090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 3112dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); 31290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 31390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 31446d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static void GenKey(const GrGeometryProcessor& gp, 3159b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 316cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 317b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 3189b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = bt.cast<BatchTracker>(); 319e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const EllipseEdgeEffect& ee = gp.cast<EllipseEdgeEffect>(); 320e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt uint16_t key = ee.isStroked() ? 0x1 : 0x0; 321e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt key |= local.fUsesLocalCoords && ee.localMatrix().hasPerspective() ? 0x2 : 0x0; 3228fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key << 16 | local.fInputColorType); 32390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 32490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 3259b98932adaceb7ad0a617ade16616923f6bffe84joshualitt virtual void setData(const GrGLProgramDataManager& pdman, 3269b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& gp, 32736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 328ee2af95db72152dfa61c841875df0594ca93437djoshualitt 3299b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = bt.cast<BatchTracker>(); 3309b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 3319b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 3329b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 3339b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 3349b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 3359b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 33690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 33790c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 338e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt void setTransformData(const GrPrimitiveProcessor& primProc, 339e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const GrGLProgramDataManager& pdman, 340e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt int index, 341e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt const SkTArray<const GrCoordTransform*, true>& transforms) override { 342e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt this->setTransformDataHelper<EllipseEdgeEffect>(primProc, pdman, index, transforms); 343e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt } 344e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt 34590c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org private: 3469b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 3479b98932adaceb7ad0a617ade16616923f6bffe84joshualitt UniformHandle fColorUniform; 3489b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 349249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 35090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org }; 35190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 352eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt virtual void getGLProcessorKey(const GrBatchTracker& bt, 353cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps& caps, 35436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrProcessorKeyBuilder* b) const override { 355eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLProcessor::GenKey(*this, bt, caps, b); 356eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 357eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 358abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, 359cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&) const override { 360eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GLProcessor, (*this, bt)); 361eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 362eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 36336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { 3649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt BatchTracker* local = bt->cast<BatchTracker>(); 3659b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); 366290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 3679b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 3689b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 36990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.orgprivate: 370d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt EllipseEdgeEffect(GrColor color, bool stroke, const SkMatrix& localMatrix) 371e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt : fColor(color) 372e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt , fLocalMatrix(localMatrix) { 373eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<EllipseEdgeEffect>(); 37471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType)); 37571c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInEllipseOffset = &this->addVertexAttrib(Attribute("inEllipseOffset", 3762dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt kVec2f_GrVertexAttribType)); 37771c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInEllipseRadii = &this->addVertexAttrib(Attribute("inEllipseRadii", 3782dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt kVec4f_GrVertexAttribType)); 37990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org fStroke = stroke; 38090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org } 38190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 3829b98932adaceb7ad0a617ade16616923f6bffe84joshualitt struct BatchTracker { 3839b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 3849b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 385290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 3869b98932adaceb7ad0a617ade16616923f6bffe84joshualitt }; 3879b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 38871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInPosition; 38971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInEllipseOffset; 39071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInEllipseRadii; 39188c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt GrColor fColor; 392e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt SkMatrix fLocalMatrix; 39390c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org bool fStroke; 39490c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 395b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 39690c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 397249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGeometryProcessor INHERITED; 39890c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org}; 39990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 400b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(EllipseEdgeEffect); 40190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 402b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, 403b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext* context, 404b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 405b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 4068059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt return EllipseEdgeEffect::Create(GrRandomColor(random), 4078059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt random->nextBool(), 4084eaf9cef5a76098f78efac30beb966ac833d32c2joshualitt GrTest::TestMatrix(random)); 40990c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org} 41090c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 41190c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 41290c240aca0c0f4cd71bbde11f20c7949b2a37c1ecommit-bot@chromium.org 4135242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org/** 4146fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com * The output of this effect is a modulation of the input color and coverage for an ellipse, 4155242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * specified as a 2D offset from center for both the outer and inner paths (if stroked). The 4165242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * implict equation used is for a unit circle (x^2 + y^2 - 1 = 0) and the edge corrected by 4175242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * using differentials. 4185242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * 4195242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org * The result is device-independent and can be used with any affine matrix. 4205242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org */ 4215242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 422249af15fb82833d2274850c589812b6e69df0033joshualittclass DIEllipseEdgeEffect : public GrGeometryProcessor { 4235242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgpublic: 4245242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org enum Mode { kStroke = 0, kHairline, kFill }; 4255242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 4268059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt static GrGeometryProcessor* Create(GrColor color, const SkMatrix& viewMatrix, Mode mode) { 4278059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt return SkNEW_ARGS(DIEllipseEdgeEffect, (color, viewMatrix, mode)); 4285242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 4295242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 4305242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org virtual ~DIEllipseEdgeEffect() {} 4315242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 43236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "DIEllipseEdge"; } 4335242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 43471c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inPosition() const { return fInPosition; } 43571c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inEllipseOffsets0() const { return fInEllipseOffsets0; } 43671c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* inEllipseOffsets1() const { return fInEllipseOffsets1; } 43788c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt GrColor color() const { return fColor; } 438e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt const SkMatrix& viewMatrix() const { return fViewMatrix; } 439249af15fb82833d2274850c589812b6e69df0033joshualitt 4405242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org inline Mode getMode() const { return fMode; } 4415242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 442b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt class GLProcessor : public GrGLGeometryProcessor { 4435242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org public: 444eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLProcessor(const GrGeometryProcessor&, 4459b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker&) 4469b98932adaceb7ad0a617ade16616923f6bffe84joshualitt : fColor(GrColor_ILLEGAL) {} 4475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 44836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ 4492dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt const DIEllipseEdgeEffect& ee = args.fGP.cast<DIEllipseEdgeEffect>(); 4509b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLGPBuilder* pb = args.fPB; 4519b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = args.fBT.cast<BatchTracker>(); 4522dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); 4535242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 454abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit attributes 455abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt vsBuilder->emitAttributes(ee); 456abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 45774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag offsets0(kVec2f_GrSLType); 45874077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("EllipseOffsets0", &offsets0); 45974077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt vsBuilder->codeAppendf("%s = %s;", offsets0.vsOut(), 4602dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt ee.inEllipseOffsets0()->fName); 46174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt 46274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt GrGLVertToFrag offsets1(kVec2f_GrSLType); 46374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt args.fPB->addVarying("EllipseOffsets1", &offsets1); 46474077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt vsBuilder->codeAppendf("%s = %s;", offsets1.vsOut(), 4652dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt ee.inEllipseOffsets1()->fName); 4662dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt 4679b98932adaceb7ad0a617ade16616923f6bffe84joshualitt // Setup pass through color 4689b98932adaceb7ad0a617ade16616923f6bffe84joshualitt this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, 4699b98932adaceb7ad0a617ade16616923f6bffe84joshualitt &fColorUniform); 4709b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 471abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // Setup position 472dd2198701b0ec9da61ecf73418cad03642d715e7joshualitt this->setupPosition(pb, gpArgs, ee.inPosition()->fName, ee.viewMatrix()); 473abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 474abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt // emit transforms 47546d36f0e7b709a077c647841eee23bd3efdc4117robertphillips this->emitTransforms(args.fPB, gpArgs->fPositionVar, ee.inPosition()->fName, 476e3ababe44315452cd33b96a18ce316ede09ff3c3joshualitt args.fTransformsIn, args.fTransformsOut); 4774973d9da4aeb7c4d8b8e67e167586c7cc9534eeejoshualitt 47829bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 47930ba436f04e61d4505fb854d5fc56079636e0788joshualitt SkAssertResult(fsBuilder->enableFeature( 48030ba436f04e61d4505fb854d5fc56079636e0788joshualitt GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); 4815242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // for outer curve 48274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 scaledOffset = %s.xy;", offsets0.fsIn()); 48374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float test = dot(scaledOffset, scaledOffset) - 1.0;"); 48474077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 duvdx = dFdx(%s);", offsets0.fsIn()); 48574077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 duvdy = dFdy(%s);", offsets0.fsIn()); 48674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("vec2 grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y," 48774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);", 48874077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn(), offsets0.fsIn()); 48974077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt 49074077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float grad_dot = dot(grad, grad);"); 4911b035d82d2b8b50ae334463edd06e4c5e0639311commit-bot@chromium.org // avoid calling inversesqrt on zero. 49274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);"); 49374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float invlen = inversesqrt(grad_dot);"); 4942dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (kHairline == ee.getMode()) { 4955242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // can probably do this with one step 49674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float edgeAlpha = clamp(1.0-test*invlen, 0.0, 1.0);"); 49774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("edgeAlpha *= clamp(1.0+test*invlen, 0.0, 1.0);"); 4985242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } else { 49974077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("float edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);"); 5005242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 5015242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 5025242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // for inner curve 5032dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt if (kStroke == ee.getMode()) { 50474077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("scaledOffset = %s.xy;", offsets1.fsIn()); 50574077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;"); 50674077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("duvdx = dFdx(%s);", offsets1.fsIn()); 50774077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("duvdy = dFdy(%s);", offsets1.fsIn()); 50874077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppendf("grad = vec2(2.0*%s.x*duvdx.x + 2.0*%s.y*duvdx.y," 50974077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt " 2.0*%s.x*duvdy.x + 2.0*%s.y*duvdy.y);", 51074077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt offsets1.fsIn(), offsets1.fsIn(), offsets1.fsIn(), 51174077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt offsets1.fsIn()); 51274077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));"); 51374077b9941ed3f73d92ba978ef29bf3e6f630cbcjoshualitt fsBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);"); 5145242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 5155242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 5162dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt fsBuilder->codeAppendf("%s = vec4(edgeAlpha);", args.fOutputCoverage); 5175242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 5185242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 51946d36f0e7b709a077c647841eee23bd3efdc4117robertphillips static void GenKey(const GrGeometryProcessor& gp, 5209b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrBatchTracker& bt, 521cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&, 522b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 5239b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = bt.cast<BatchTracker>(); 52446d36f0e7b709a077c647841eee23bd3efdc4117robertphillips const DIEllipseEdgeEffect& ellipseEffect = gp.cast<DIEllipseEdgeEffect>(); 5258fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt uint16_t key = ellipseEffect.getMode(); 526e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt key |= ComputePosKey(ellipseEffect.viewMatrix()) << 9; 5278fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt b->add32(key << 16 | local.fInputColorType); 5285242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 5295242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 5309b98932adaceb7ad0a617ade16616923f6bffe84joshualitt virtual void setData(const GrGLProgramDataManager& pdman, 5319b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const GrPrimitiveProcessor& gp, 53236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const GrBatchTracker& bt) override { 533e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt const DIEllipseEdgeEffect& dee = gp.cast<DIEllipseEdgeEffect>(); 534e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt this->setUniformViewMatrix(pdman, dee.viewMatrix()); 535ee2af95db72152dfa61c841875df0594ca93437djoshualitt 5369b98932adaceb7ad0a617ade16616923f6bffe84joshualitt const BatchTracker& local = bt.cast<BatchTracker>(); 5379b98932adaceb7ad0a617ade16616923f6bffe84joshualitt if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { 5389b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGLfloat c[4]; 5399b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColorToRGBAFloat(local.fColor, c); 5409b98932adaceb7ad0a617ade16616923f6bffe84joshualitt pdman.set4fv(fColorUniform, 1, c); 5419b98932adaceb7ad0a617ade16616923f6bffe84joshualitt fColor = local.fColor; 5429b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 5435242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 5445242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 5455242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org private: 5469b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 5479b98932adaceb7ad0a617ade16616923f6bffe84joshualitt UniformHandle fColorUniform; 5489b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 549249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGLGeometryProcessor INHERITED; 5505242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org }; 5515242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 552eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt virtual void getGLProcessorKey(const GrBatchTracker& bt, 553cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps& caps, 55436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrProcessorKeyBuilder* b) const override { 555eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLProcessor::GenKey(*this, bt, caps, b); 556eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 557eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 558abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt virtual GrGLPrimitiveProcessor* createGLInstance(const GrBatchTracker& bt, 559cfc18867d982119d9dc2888bf09f1093012daaddjvanverth const GrGLSLCaps&) const override { 560eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GLProcessor, (*this, bt)); 561eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt } 562eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 56336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(GrBatchTracker* bt, const GrPipelineInfo& init) const override { 5649b98932adaceb7ad0a617ade16616923f6bffe84joshualitt BatchTracker* local = bt->cast<BatchTracker>(); 5659b98932adaceb7ad0a617ade16616923f6bffe84joshualitt local->fInputColorType = GetColorInputType(&local->fColor, this->color(), init, false); 566290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt local->fUsesLocalCoords = init.fUsesLocalCoords; 5679b98932adaceb7ad0a617ade16616923f6bffe84joshualitt } 5689b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 5695242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.orgprivate: 5708059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt DIEllipseEdgeEffect(GrColor color, const SkMatrix& viewMatrix, Mode mode) 571e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt : fColor(color) 572e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt , fViewMatrix(viewMatrix) { 573eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<DIEllipseEdgeEffect>(); 574c375b0b5c5c03d381111bf7bff12507d5ed24769senorblanco fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertexAttribType, 575c375b0b5c5c03d381111bf7bff12507d5ed24769senorblanco kHigh_GrSLPrecision)); 57671c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInEllipseOffsets0 = &this->addVertexAttrib(Attribute("inEllipseOffsets0", 5772dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt kVec2f_GrVertexAttribType)); 57871c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt fInEllipseOffsets1 = &this->addVertexAttrib(Attribute("inEllipseOffsets1", 5792dd1ae016d7f297b433c3ea3a771ef8e01657c1fjoshualitt kVec2f_GrVertexAttribType)); 5805242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org fMode = mode; 5815242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 5825242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 5839b98932adaceb7ad0a617ade16616923f6bffe84joshualitt struct BatchTracker { 5849b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrGPInput fInputColorType; 5859b98932adaceb7ad0a617ade16616923f6bffe84joshualitt GrColor fColor; 586290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 5879b98932adaceb7ad0a617ade16616923f6bffe84joshualitt }; 5889b98932adaceb7ad0a617ade16616923f6bffe84joshualitt 58971c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInPosition; 59071c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInEllipseOffsets0; 59171c9260e6fa1798ad1e41b2c2ae9b3cce08bb610joshualitt const Attribute* fInEllipseOffsets1; 59288c23fc6e8ed0243159fd17d815b4f813805647bjoshualitt GrColor fColor; 593e578a95d3ab16544794b94da4e7ae13fc2ce6244joshualitt SkMatrix fViewMatrix; 5945242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org Mode fMode; 5955242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 596b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_GEOMETRY_PROCESSOR_TEST; 5975242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 598249af15fb82833d2274850c589812b6e69df0033joshualitt typedef GrGeometryProcessor INHERITED; 5995242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org}; 6005242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 601b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_GEOMETRY_PROCESSOR_TEST(DIEllipseEdgeEffect); 6025242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 603b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, 604b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext* context, 605b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps&, 606b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture* textures[]) { 6078059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt return DIEllipseEdgeEffect::Create(GrRandomColor(random), 6084eaf9cef5a76098f78efac30beb966ac833d32c2joshualitt GrTest::TestMatrix(random), 6098059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt (Mode)(random->nextRangeU(0,2))); 6105242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org} 6115242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 6125242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 6135242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 6149853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrOvalRenderer::drawOval(GrDrawTarget* target, 6158dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 6162e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 6178059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 6189853ccef19c200be93a6211f32589fa82a53067cjoshualitt bool useAA, 6199853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkRect& oval, 6209853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkStrokeRec& stroke) 62181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org{ 622ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisampled(); 623e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org 624e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org if (!useCoverageAA) { 62581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org return false; 62681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org } 62781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 6287e32851d5473d14db5c396f5877e3dfcb7b19f6dskia.committer@gmail.com // we can draw circles 6298059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(viewMatrix)) { 6308dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel this->drawCircle(target, pipelineBuilder, color, viewMatrix, useCoverageAA, oval, stroke); 6315242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // if we have shader derivative support, render as device-independent 632e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth } else if (target->caps()->shaderCaps()->shaderDerivativeSupport()) { 6338dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel return this->drawDIEllipse(target, pipelineBuilder, color, viewMatrix, useCoverageAA, oval, 6348059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt stroke); 6355242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // otherwise axis-aligned ellipses only 6368059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt } else if (viewMatrix.rectStaysRect()) { 6378dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel return this->drawEllipse(target, pipelineBuilder, color, viewMatrix, useCoverageAA, oval, 6388dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel stroke); 63981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org } else { 64081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org return false; 64181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org } 64281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 64381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org return true; 64481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org} 64581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 646f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 647f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 64876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittclass CircleBatch : public GrBatch { 64976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittpublic: 65076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct Geometry { 65176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 65276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix fViewMatrix; 65376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fInnerRadius; 65476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fOuterRadius; 65576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fStroke; 656bc227140ffea6eb15e2e8b147eb6d8ec6228d95aegdaniel SkRect fDevBounds; 65776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 65876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 659ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon static GrBatch* Create(const Geometry& geometry) { return SkNEW_ARGS(CircleBatch, (geometry)); } 66076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 66136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "CircleBatch"; } 66276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 66336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 66476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 66576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setKnownFourComponents(fGeoData[0].fColor); 66676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 66776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 66836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 66976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setUnknownSingleComponent(); 67076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 67176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 67236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(const GrPipelineInfo& init) override { 67376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Handle any color overrides 67476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (init.fColorIgnored) { 67576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 67676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } else if (GrColor_ILLEGAL != init.fOverrideColor) { 67776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = init.fOverrideColor; 67876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 67976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 68076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // setup batch properties 68176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColorIgnored = init.fColorIgnored; 68276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColor = fGeoData[0].fColor; 68376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fStroke = fGeoData[0].fStroke; 68476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 68576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fCoverageIgnored = init.fCoverageIgnored; 68676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 68776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 68836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 68976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix invert; 69076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (!this->viewMatrix().invert(&invert)) { 69176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return; 69276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 69376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 69476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 69576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkAutoTUnref<GrGeometryProcessor> gp(CircleEdgeEffect::Create(this->color(), 69676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->stroke(), 69776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt invert)); 69876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 69976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt batchTarget->initDraw(gp, pipeline); 70076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 70176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO this is hacky, but the only way we have to initialize the GP is to use the 70276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch 70376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // everywhere we can remove this nastiness 70476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrPipelineInfo init; 70576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fColorIgnored = fBatch.fColorIgnored; 70676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fOverrideColor = GrColor_ILLEGAL; 70776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fCoverageIgnored = fBatch.fCoverageIgnored; 70876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fUsesLocalCoords = this->usesLocalCoords(); 70976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt gp->initBatchTracker(batchTarget->currentBatchTracker(), init); 71076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 71176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 71276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 71376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(vertexStride == sizeof(CircleVertex)); 714b5238a7571c243ba4a154a62575570c3078b3741bsalomon QuadHelper helper; 715b5238a7571c243ba4a154a62575570c3078b3741bsalomon CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget, vertexStride, 716b5238a7571c243ba4a154a62575570c3078b3741bsalomon instanceCount)); 717b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts) { 7184b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 7194b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 7204b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 72176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 722b5238a7571c243ba4a154a62575570c3078b3741bsalomon Geometry& geom = fGeoData[i]; 72376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 724b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar innerRadius = geom.fInnerRadius; 725b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar outerRadius = geom.fOuterRadius; 72676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 727b5238a7571c243ba4a154a62575570c3078b3741bsalomon const SkRect& bounds = geom.fDevBounds; 72876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 72976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // The inner radius in the vertex data must be specified in normalized space. 73076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt innerRadius = innerRadius / outerRadius; 73176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); 73276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOffset = SkPoint::Make(-1, -1); 73376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOuterRadius = outerRadius; 73476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fInnerRadius = innerRadius; 73576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 73676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); 73776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOffset = SkPoint::Make(-1, 1); 73876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOuterRadius = outerRadius; 73976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fInnerRadius = innerRadius; 74076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 74176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); 74276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOffset = SkPoint::Make(1, 1); 74376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOuterRadius = outerRadius; 74476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fInnerRadius = innerRadius; 74576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 74676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); 74776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOffset = SkPoint::Make(1, -1); 74876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOuterRadius = outerRadius; 74976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fInnerRadius = innerRadius; 75076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 751b5238a7571c243ba4a154a62575570c3078b3741bsalomon verts += kVerticesPerQuad; 75276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 753e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon helper.issueDraw(batchTarget); 75476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 75576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 75676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 75776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 75876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittprivate: 75976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt CircleBatch(const Geometry& geometry) { 76076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->initClassID<CircleBatch>(); 76176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back(geometry); 76299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 76399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->setBounds(geometry.fDevBounds); 76476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 76576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 76636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onCombineIfPossible(GrBatch* t) override { 76776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt CircleBatch* that = t->cast<CircleBatch>(); 76876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 76976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO use vertex color to avoid breaking batches 77076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->color() != that->color()) { 77176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 77276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 77376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 77476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->stroke() != that->stroke()) { 77576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 77676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 77776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 77876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 77976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 78076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 78176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 78276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 78376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 78499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 78576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 78676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 78776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 78876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor color() const { return fBatch.fColor; } 78976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 79076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 79176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool stroke() const { return fBatch.fStroke; } 79276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 79376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct BatchTracker { 79476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 79576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fStroke; 79676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fUsesLocalCoords; 79776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fColorIgnored; 79876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fCoverageIgnored; 79976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 80076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 80176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt BatchTracker fBatch; 80276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 80376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 80476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 8053e708c53f79a04b588b6ca8e535e61f986d80b47joshualittstatic GrBatch* create_circle_batch(GrColor color, 8063e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkMatrix& viewMatrix, 8073e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA, 8083e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRect& circle, 809d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt const SkStrokeRec& stroke) { 810972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); 8118059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix.mapPoints(¢er, 1); 8128059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width())); 8138059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth()); 81481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 81581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkStrokeRec::Style style = stroke.getStyle(); 8160a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 8170a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org SkStrokeRec::kHairline_Style == style; 8180a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 8197e32851d5473d14db5c396f5877e3dfcb7b19f6dskia.committer@gmail.com 82081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkScalar innerRadius = 0.0f; 82181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkScalar outerRadius = radius; 82281312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org SkScalar halfWidth = 0; 8230a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (hasStroke) { 82481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org if (SkScalarNearlyZero(strokeWidth)) { 82581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org halfWidth = SK_ScalarHalf; 82681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org } else { 82781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org halfWidth = SkScalarHalf(strokeWidth); 82881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org } 82981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 83081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org outerRadius += halfWidth; 8310a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (isStrokeOnly) { 8326bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org innerRadius = radius - halfWidth; 83381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org } 83481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org } 83581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 836ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon // The radii are outset for two reasons. First, it allows the shader to simply perform simpler 837ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon // computation because the computed alpha is zero, rather than 50%, at the radius. 838ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon // Second, the outer radius is used to compute the verts of the bounding box that is rendered 839ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon // and the outset ensures the box will cover all partially covered by the circle. 84058e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com outerRadius += SK_ScalarHalf; 84158e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com innerRadius -= SK_ScalarHalf; 84258e30fe8649deb1ffc5bda3627945228b028c439bsalomon@google.com 84376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt CircleBatch::Geometry geometry; 84476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fViewMatrix = viewMatrix; 84576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fColor = color; 84676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fInnerRadius = innerRadius; 84776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fOuterRadius = outerRadius; 84876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fStroke = isStrokeOnly && innerRadius > 0; 849d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt geometry.fDevBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY - outerRadius, 850d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt center.fX + outerRadius, center.fY + outerRadius); 85176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 8523e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return CircleBatch::Create(geometry); 8533e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 8543e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 8553e708c53f79a04b588b6ca8e535e61f986d80b47joshualittvoid GrOvalRenderer::drawCircle(GrDrawTarget* target, 8563e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrPipelineBuilder* pipelineBuilder, 8573e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color, 8583e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkMatrix& viewMatrix, 8593e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA, 8603e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRect& circle, 8613e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkStrokeRec& stroke) { 8623e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkAutoTUnref<GrBatch> batch(create_circle_batch(color, viewMatrix, useCoverageAA, circle, 863d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt stroke)); 86499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt target->drawBatch(pipelineBuilder, batch); 86581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org} 86681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 867f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 868f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 86976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittclass EllipseBatch : public GrBatch { 87076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittpublic: 87176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct Geometry { 87276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 87376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix fViewMatrix; 87476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fXRadius; 87576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fYRadius; 87676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fInnerXRadius; 87776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fInnerYRadius; 87876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fStroke; 879bc227140ffea6eb15e2e8b147eb6d8ec6228d95aegdaniel SkRect fDevBounds; 88076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 88176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 88276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt static GrBatch* Create(const Geometry& geometry) { 88376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return SkNEW_ARGS(EllipseBatch, (geometry)); 88476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 88576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 88636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "EllipseBatch"; } 88776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 88836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 88976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 89076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setKnownFourComponents(fGeoData[0].fColor); 89176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 89236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 89376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setUnknownSingleComponent(); 89476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 89576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 89636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(const GrPipelineInfo& init) override { 89776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Handle any color overrides 89876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (init.fColorIgnored) { 89976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 90076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } else if (GrColor_ILLEGAL != init.fOverrideColor) { 90176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = init.fOverrideColor; 90276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 90376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 90476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // setup batch properties 90576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColorIgnored = init.fColorIgnored; 90676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColor = fGeoData[0].fColor; 90776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fStroke = fGeoData[0].fStroke; 90876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 90976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fCoverageIgnored = init.fCoverageIgnored; 91076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 91176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 91236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 91376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix invert; 91476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (!this->viewMatrix().invert(&invert)) { 91576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return; 91676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 91776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 91876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 91976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkAutoTUnref<GrGeometryProcessor> gp(EllipseEdgeEffect::Create(this->color(), 92076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->stroke(), 92176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt invert)); 92276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 92376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt batchTarget->initDraw(gp, pipeline); 92476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 92576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO this is hacky, but the only way we have to initialize the GP is to use the 92676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch 92776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // everywhere we can remove this nastiness 92876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrPipelineInfo init; 92976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fColorIgnored = fBatch.fColorIgnored; 93076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fOverrideColor = GrColor_ILLEGAL; 93176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fCoverageIgnored = fBatch.fCoverageIgnored; 93276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fUsesLocalCoords = this->usesLocalCoords(); 93376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt gp->initBatchTracker(batchTarget->currentBatchTracker(), init); 93476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 93576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 936b5238a7571c243ba4a154a62575570c3078b3741bsalomon QuadHelper helper; 93776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 93819e0058a650a9e4dc9c35ed26c5e91916bcc0601joshualitt SkASSERT(vertexStride == sizeof(EllipseVertex)); 939b5238a7571c243ba4a154a62575570c3078b3741bsalomon EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( 940b5238a7571c243ba4a154a62575570c3078b3741bsalomon helper.init(batchTarget, vertexStride, instanceCount)); 941b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts) { 9424b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 9434b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 9444b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 94576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 946b5238a7571c243ba4a154a62575570c3078b3741bsalomon Geometry& geom = fGeoData[i]; 94776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 948b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar xRadius = geom.fXRadius; 949b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar yRadius = geom.fYRadius; 95076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 95176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Compute the reciprocals of the radii here to save time in the shader 95276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar xRadRecip = SkScalarInvert(xRadius); 95376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yRadRecip = SkScalarInvert(yRadius); 954b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar xInnerRadRecip = SkScalarInvert(geom.fInnerXRadius); 955b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar yInnerRadRecip = SkScalarInvert(geom.fInnerYRadius); 95676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 957b5238a7571c243ba4a154a62575570c3078b3741bsalomon const SkRect& bounds = geom.fDevBounds; 95876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 95976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // The inner radius in the vertex data must be specified in normalized space. 96076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); 96176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOffset = SkPoint::Make(-xRadius, -yRadius); 96276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 96376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 96476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 96576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); 96676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOffset = SkPoint::Make(-xRadius, yRadius); 96776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 96876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 96976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 97076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); 97176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOffset = SkPoint::Make(xRadius, yRadius); 97276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 97376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 97476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 97576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); 97676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOffset = SkPoint::Make(xRadius, -yRadius); 97776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 97876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 97976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 980b5238a7571c243ba4a154a62575570c3078b3741bsalomon verts += kVerticesPerQuad; 98176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 982e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon helper.issueDraw(batchTarget); 98376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 98476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 98576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 98676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 98776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittprivate: 98876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt EllipseBatch(const Geometry& geometry) { 98976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->initClassID<EllipseBatch>(); 99076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back(geometry); 99199c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 99299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->setBounds(geometry.fDevBounds); 99376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 99476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 99536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onCombineIfPossible(GrBatch* t) override { 99676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt EllipseBatch* that = t->cast<EllipseBatch>(); 99776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 99876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO use vertex color to avoid breaking batches 99976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->color() != that->color()) { 100076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 100176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 100276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 100376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->stroke() != that->stroke()) { 100476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 100576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 100676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 100776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 100876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 100976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 101076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 101176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 101276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 101399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 101476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 101576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 101676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 101776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor color() const { return fBatch.fColor; } 101876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 101976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 102076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool stroke() const { return fBatch.fStroke; } 102176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 102276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct BatchTracker { 102376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 102476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fStroke; 102576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fUsesLocalCoords; 102676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fColorIgnored; 102776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fCoverageIgnored; 102876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 102976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 103076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt BatchTracker fBatch; 103176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 103276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 103376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 10343e708c53f79a04b588b6ca8e535e61f986d80b47joshualittstatic GrBatch* create_ellipse_batch(GrColor color, 10353e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkMatrix& viewMatrix, 10363e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA, 10373e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRect& ellipse, 1038d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt const SkStrokeRec& stroke) { 103981312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#ifdef SK_DEBUG 104081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org { 104181312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org // we should have checked for this previously 10428059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt bool isAxisAlignedEllipse = viewMatrix.rectStaysRect(); 1043e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org SkASSERT(useCoverageAA && isAxisAlignedEllipse); 104481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org } 104581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#endif 104681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 10470c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org // do any matrix crunching before we reset the draw state for device coords 1048972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); 10498059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix.mapPoints(¢er, 1); 10500c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org SkScalar ellipseXRadius = SkScalarHalf(ellipse.width()); 10510c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org SkScalar ellipseYRadius = SkScalarHalf(ellipse.height()); 10528059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*ellipseXRadius + 10538059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMSkewY]*ellipseYRadius); 10548059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*ellipseXRadius + 10558059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMScaleY]*ellipseYRadius); 105681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 10570c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org // do (potentially) anisotropic mapping of stroke 10580c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org SkVector scaledStroke; 10590c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org SkScalar strokeWidth = stroke.getWidth(); 10608059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] + 10618059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMSkewY])); 10628059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] + 10638059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMScaleY])); 10640c888286f7db7e9cd861b2e425a17e109601d3facommit-bot@chromium.org 10656bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org SkStrokeRec::Style style = stroke.getStyle(); 10660a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 10670a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org SkStrokeRec::kHairline_Style == style; 10680a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 10696bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 10705242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org SkScalar innerXRadius = 0; 10715242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org SkScalar innerYRadius = 0; 10720a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (hasStroke) { 10736bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org if (SkScalarNearlyZero(scaledStroke.length())) { 10746bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); 10756bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } else { 10766bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org scaledStroke.scale(SK_ScalarHalf); 10776bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } 10786bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 10796bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // we only handle thick strokes for near-circular ellipses 10806bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org if (scaledStroke.length() > SK_ScalarHalf && 10816bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) { 10823e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return NULL; 10836bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } 10846bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 10856bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // we don't handle it if curvature of the stroke is less than curvature of the ellipse 10866bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY)*xRadius || 10876bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX)*yRadius) { 10883e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return NULL; 10896bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } 10906bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 10916bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // this is legit only if scale & translation (which should be the case at the moment) 10920a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (isStrokeOnly) { 10936bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org innerXRadius = xRadius - scaledStroke.fX; 10946bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org innerYRadius = yRadius - scaledStroke.fY; 10956bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } 10966bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 10976bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org xRadius += scaledStroke.fX; 10986bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org yRadius += scaledStroke.fY; 10996bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } 11006bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 11010a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org // We've extended the outer x radius out half a pixel to antialias. 11020a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org // This will also expand the rect so all the pixels will be captured. 11036bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // TODO: Consider if we should use sqrt(2)/2 instead 11040a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org xRadius += SK_ScalarHalf; 11050a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org yRadius += SK_ScalarHalf; 11060a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org 110776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt EllipseBatch::Geometry geometry; 110876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fViewMatrix = viewMatrix; 110976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fColor = color; 111076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fXRadius = xRadius; 111176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fYRadius = yRadius; 111276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fInnerXRadius = innerXRadius; 111376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fInnerYRadius = innerYRadius; 111476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; 1115d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt geometry.fDevBounds = SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRadius, 1116d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt center.fX + xRadius, center.fY + yRadius); 111781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org 11183e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return EllipseBatch::Create(geometry); 11193e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 11200a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org 11213e708c53f79a04b588b6ca8e535e61f986d80b47joshualittbool GrOvalRenderer::drawEllipse(GrDrawTarget* target, 11223e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrPipelineBuilder* pipelineBuilder, 11233e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color, 11243e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkMatrix& viewMatrix, 11253e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA, 11263e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRect& ellipse, 11273e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkStrokeRec& stroke) { 11283e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkAutoTUnref<GrBatch> batch(create_ellipse_batch(color, viewMatrix, useCoverageAA, ellipse, 1129d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt stroke)); 11303e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt if (!batch) { 11313e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return false; 11323e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt } 11333e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 113499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt target->drawBatch(pipelineBuilder, batch); 113576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 113676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt} 11370a6cb602e5866f7a8cd1630d0c907749f5182837commit-bot@chromium.org 113876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt///////////////////////////////////////////////////////////////////////////////////////////////// 11394674676438051c31a991fdab72efea3c7d0ca5a3skia.committer@gmail.com 114076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittclass DIEllipseBatch : public GrBatch { 114176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittpublic: 114276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct Geometry { 114376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 114476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix fViewMatrix; 114576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fXRadius; 114676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fYRadius; 114776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fInnerXRadius; 114876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fInnerYRadius; 114976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fGeoDx; 115076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fGeoDy; 115176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt DIEllipseEdgeEffect::Mode fMode; 11529ef1bb1375e66d9aac1124e005b500cb6d9caf01egdaniel SkRect fBounds; 115376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 1154c4f2ecaa475756bda48684b1158ec6b8bbdd1016jvanverth@google.com 115599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt static GrBatch* Create(const Geometry& geometry, const SkRect& bounds) { 115699c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt return SkNEW_ARGS(DIEllipseBatch, (geometry, bounds)); 115776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 115876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 115936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "DIEllipseBatch"; } 116076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 116136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 116276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 116376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setKnownFourComponents(fGeoData[0].fColor); 116476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 116536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 116676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setUnknownSingleComponent(); 116776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 116876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 116936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(const GrPipelineInfo& init) override { 117076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Handle any color overrides 117176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (init.fColorIgnored) { 117276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 117376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } else if (GrColor_ILLEGAL != init.fOverrideColor) { 117476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = init.fOverrideColor; 117576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 117676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 117776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // setup batch properties 117876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColorIgnored = init.fColorIgnored; 117976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColor = fGeoData[0].fColor; 118076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fMode = fGeoData[0].fMode; 118176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 118276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fCoverageIgnored = init.fCoverageIgnored; 118376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 118476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 118536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 118676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 118776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkAutoTUnref<GrGeometryProcessor> gp(DIEllipseEdgeEffect::Create(this->color(), 118876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->viewMatrix(), 118976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->mode())); 119076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 119176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt batchTarget->initDraw(gp, pipeline); 119276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 119376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO this is hacky, but the only way we have to initialize the GP is to use the 119476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch 119576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // everywhere we can remove this nastiness 119676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrPipelineInfo init; 119776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fColorIgnored = fBatch.fColorIgnored; 119876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fOverrideColor = GrColor_ILLEGAL; 119976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fCoverageIgnored = fBatch.fCoverageIgnored; 120076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fUsesLocalCoords = this->usesLocalCoords(); 120176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt gp->initBatchTracker(batchTarget->currentBatchTracker(), init); 120276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 120376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 120476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 120519e0058a650a9e4dc9c35ed26c5e91916bcc0601joshualitt SkASSERT(vertexStride == sizeof(DIEllipseVertex)); 1206b5238a7571c243ba4a154a62575570c3078b3741bsalomon QuadHelper helper; 1207b5238a7571c243ba4a154a62575570c3078b3741bsalomon DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>( 1208b5238a7571c243ba4a154a62575570c3078b3741bsalomon helper.init(batchTarget, vertexStride, instanceCount)); 1209b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts) { 12104b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 12114b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 12124b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 121376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 1214b5238a7571c243ba4a154a62575570c3078b3741bsalomon Geometry& geom = fGeoData[i]; 121576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1216b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar xRadius = geom.fXRadius; 1217b5238a7571c243ba4a154a62575570c3078b3741bsalomon SkScalar yRadius = geom.fYRadius; 121876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1219b5238a7571c243ba4a154a62575570c3078b3741bsalomon const SkRect& bounds = geom.fBounds; 122076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 122176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // This adjusts the "radius" to include the half-pixel border 122280ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar offsetDx = geom.fGeoDx / xRadius; 122380ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar offsetDy = geom.fGeoDy / yRadius; 122476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 122580ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar innerRatioX = xRadius / geom.fInnerXRadius; 122680ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar innerRatioY = yRadius / geom.fInnerYRadius; 122776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 122876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); 122976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy); 123076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[0].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, -innerRatioY - offsetDy); 123176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 123276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); 123376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, 1.0f + offsetDy); 123476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[1].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, innerRatioY + offsetDy); 123576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 123676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); 123776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy); 123876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerRatioY + offsetDy); 123976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 124076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); 124176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy); 124276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy); 124376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1244b5238a7571c243ba4a154a62575570c3078b3741bsalomon verts += kVerticesPerQuad; 124576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 1246e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon helper.issueDraw(batchTarget); 124776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 124876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 124976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 125076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 125176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittprivate: 125299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt DIEllipseBatch(const Geometry& geometry, const SkRect& bounds) { 125376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->initClassID<DIEllipseBatch>(); 125476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back(geometry); 125599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 125699c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->setBounds(bounds); 125776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 125876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 125936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onCombineIfPossible(GrBatch* t) override { 126076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt DIEllipseBatch* that = t->cast<DIEllipseBatch>(); 126176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 126276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO use vertex color to avoid breaking batches 126376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->color() != that->color()) { 126476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 126576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 126676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 126776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->mode() != that->mode()) { 126876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 126976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 127076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1271d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt // TODO rewrite to allow positioning on CPU 1272d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 127376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 127476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 127576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 127676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 127799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 127876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 127976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 128076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 128176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor color() const { return fBatch.fColor; } 128276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 128376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 128476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt DIEllipseEdgeEffect::Mode mode() const { return fBatch.fMode; } 128576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 128676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct BatchTracker { 128776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 128876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt DIEllipseEdgeEffect::Mode fMode; 128976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fUsesLocalCoords; 129076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fColorIgnored; 129176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fCoverageIgnored; 129276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 129376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 129476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt BatchTracker fBatch; 129576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 129676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 1297f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 12983e708c53f79a04b588b6ca8e535e61f986d80b47joshualittstatic GrBatch* create_diellipse_batch(GrColor color, 12993e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkMatrix& viewMatrix, 13003e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA, 13013e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRect& ellipse, 1302d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt const SkStrokeRec& stroke) { 1303972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); 13045242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org SkScalar xRadius = SkScalarHalf(ellipse.width()); 13056fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com SkScalar yRadius = SkScalarHalf(ellipse.height()); 13066fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com 13075242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org SkStrokeRec::Style style = stroke.getStyle(); 13086fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ? 13095242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org DIEllipseEdgeEffect::kStroke : 13106fc1b4998917791a73bf54428513940fe77dc058skia.committer@gmail.com (SkStrokeRec::kHairline_Style == style) ? 13115242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org DIEllipseEdgeEffect::kHairline : DIEllipseEdgeEffect::kFill; 13125242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 13135242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org SkScalar innerXRadius = 0; 13145242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org SkScalar innerYRadius = 0; 13155242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org if (SkStrokeRec::kFill_Style != style && SkStrokeRec::kHairline_Style != style) { 13165242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org SkScalar strokeWidth = stroke.getWidth(); 13175242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 13185242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org if (SkScalarNearlyZero(strokeWidth)) { 13195242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org strokeWidth = SK_ScalarHalf; 13205242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } else { 13215242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org strokeWidth *= SK_ScalarHalf; 13225242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 13235242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 13245242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // we only handle thick strokes for near-circular ellipses 13255242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org if (strokeWidth > SK_ScalarHalf && 13265242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) { 13273e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return NULL; 13285242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 13295242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 13305242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // we don't handle it if curvature of the stroke is less than curvature of the ellipse 13315242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius || 13325242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) { 13333e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return NULL; 13345242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 13355242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 13365242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // set inner radius (if needed) 13375242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org if (SkStrokeRec::kStroke_Style == style) { 13385242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org innerXRadius = xRadius - strokeWidth; 13395242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org innerYRadius = yRadius - strokeWidth; 13405242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 13415242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 13425242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org xRadius += strokeWidth; 13435242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org yRadius += strokeWidth; 13445242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 13455242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org if (DIEllipseEdgeEffect::kStroke == mode) { 13465242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kStroke : 13475242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org DIEllipseEdgeEffect::kFill; 13485242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org } 13495242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 13505242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org // This expands the outer rect so that after CTM we end up with a half-pixel border 13518059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar a = viewMatrix[SkMatrix::kMScaleX]; 13528059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar b = viewMatrix[SkMatrix::kMSkewX]; 13538059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar c = viewMatrix[SkMatrix::kMSkewY]; 13548059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar d = viewMatrix[SkMatrix::kMScaleY]; 135580ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar geoDx = SK_ScalarHalf / SkScalarSqrt(a*a + c*c); 135680ea19ca4bdd68c1493666a5fe7e4ce9d43ded8breed SkScalar geoDy = SK_ScalarHalf / SkScalarSqrt(b*b + d*d); 13575242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 135876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt DIEllipseBatch::Geometry geometry; 135976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fViewMatrix = viewMatrix; 136076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fColor = color; 136176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fXRadius = xRadius; 136276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fYRadius = yRadius; 136376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fInnerXRadius = innerXRadius; 136476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fInnerYRadius = innerYRadius; 136576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fGeoDx = geoDx; 136676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fGeoDy = geoDy; 136776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fMode = mode; 1368d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt geometry.fBounds = SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy, 1369d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt center.fX + xRadius + geoDx, center.fY + yRadius + geoDy); 13709ef1bb1375e66d9aac1124e005b500cb6d9caf01egdaniel 1371d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt SkRect devBounds = geometry.fBounds; 1372d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt viewMatrix.mapRect(&devBounds); 1373d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt return DIEllipseBatch::Create(geometry, devBounds); 13743e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 137576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 13763e708c53f79a04b588b6ca8e535e61f986d80b47joshualittbool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, 13773e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrPipelineBuilder* pipelineBuilder, 13783e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color, 13793e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkMatrix& viewMatrix, 13803e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA, 13813e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRect& ellipse, 13823e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkStrokeRec& stroke) { 13833e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkAutoTUnref<GrBatch> batch(create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, 1384d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt stroke)); 13853e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt if (!batch) { 13863e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return false; 13873e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt } 138899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt target->drawBatch(pipelineBuilder, batch); 13895242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org return true; 13905242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org} 13915242ed761fc60470f31ffa6ea529c2a2f6afe6f5commit-bot@chromium.org 1392f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 1393f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1394f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.orgstatic const uint16_t gRRectIndices[] = { 1395f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // corners 1396f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 0, 1, 5, 0, 5, 4, 1397f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 2, 3, 7, 2, 7, 6, 1398f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 8, 9, 13, 8, 13, 12, 1399f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 10, 11, 15, 10, 15, 14, 14002cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 1401f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // edges 1402f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1, 2, 6, 1, 6, 5, 1403f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 4, 5, 9, 4, 9, 8, 1404f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 6, 7, 11, 6, 11, 10, 1405f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 9, 10, 14, 9, 14, 13, 14062cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 1407f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // center 1408f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // we place this at the end so that we can ignore these indices when rendering stroke-only 1409f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 5, 6, 10, 5, 10, 9 1410f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org}; 1411f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 14125ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualittstatic const int kIndicesPerStrokeRRect = SK_ARRAY_COUNT(gRRectIndices) - 6; 14135ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualittstatic const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices); 14145ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualittstatic const int kVertsPerRRect = 16; 14155ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualittstatic const int kNumRRectsInIndexBuffer = 256; 14165ead6da4abaa3d8fb479fd84631138f83b7aa5b6joshualitt 1417ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomonGR_DECLARE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey); 1418ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomonGR_DECLARE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey); 1419ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomonstatic const GrIndexBuffer* ref_rrect_index_buffer(bool strokeOnly, 1420ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon GrResourceProvider* resourceProvider) { 1421ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon GR_DEFINE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey); 1422ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey); 1423ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon if (strokeOnly) { 1424ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon return resourceProvider->refOrCreateInstancedIndexBuffer( 1425ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon gRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer, kVertsPerRRect, 1426ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon gStrokeRRectOnlyIndexBufferKey); 1427ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } else { 1428ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon return resourceProvider->refOrCreateInstancedIndexBuffer( 1429ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon gRRectIndices, kIndicesPerRRect, kNumRRectsInIndexBuffer, kVertsPerRRect, 1430ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon gRRectOnlyIndexBufferKey); 1431ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 1432ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon } 1433ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon} 1434ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon 14359853ccef19c200be93a6211f32589fa82a53067cjoshualittbool GrOvalRenderer::drawDRRect(GrDrawTarget* target, 14368dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel GrPipelineBuilder* pipelineBuilder, 14372e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt GrColor color, 14388059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt const SkMatrix& viewMatrix, 14399853ccef19c200be93a6211f32589fa82a53067cjoshualitt bool useAA, 14409853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkRRect& origOuter, 14419853ccef19c200be93a6211f32589fa82a53067cjoshualitt const SkRRect& origInner) { 14428af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon bool applyAA = useAA && 14430bdeec9640640922eb6b0a9f798bcd85eb898f29egdaniel !pipelineBuilder->getRenderTarget()->isMultisampled(); 14446be6f7cb66b277e7b1ce13d09b635fb8e09a2f68bsalomon GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; 14450a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (!origInner.isEmpty()) { 14460a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org SkTCopyOnFirstWrite<SkRRect> inner(origInner); 14478059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!viewMatrix.isIdentity()) { 14488059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!origInner.transform(viewMatrix, inner.writable())) { 14490a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org return false; 14500a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 14510a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 1452b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType = applyAA ? 1453b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt kInverseFillAA_GrProcessorEdgeType : 1454b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt kInverseFillBW_GrProcessorEdgeType; 14552e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt // TODO this needs to be a geometry processor 1456b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); 1457b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (NULL == fp) { 14580a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org return false; 14590a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 14606be6f7cb66b277e7b1ce13d09b635fb8e09a2f68bsalomon arfp.set(pipelineBuilder); 14618dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel pipelineBuilder->addCoverageProcessor(fp)->unref(); 14620a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 14630a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 14640a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); 14658dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel if (this->drawRRect(target, pipelineBuilder, color, viewMatrix, useAA, origOuter, fillRec)) { 14668af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon return true; 14678af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon } 14688af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon 14698af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon SkASSERT(!origOuter.isEmpty()); 14708af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon SkTCopyOnFirstWrite<SkRRect> outer(origOuter); 14718059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!viewMatrix.isIdentity()) { 14728059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!origOuter.transform(viewMatrix, outer.writable())) { 14738af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon return false; 14748af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon } 14758af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon } 1476b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType = applyAA ? kFillAA_GrProcessorEdgeType : 147776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt kFillBW_GrProcessorEdgeType; 1478b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* effect = GrRRectEffect::Create(edgeType, *outer); 14798af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon if (NULL == effect) { 14808af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon return false; 14818af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon } 14826be6f7cb66b277e7b1ce13d09b635fb8e09a2f68bsalomon if (!arfp.isSet()) { 14836be6f7cb66b277e7b1ce13d09b635fb8e09a2f68bsalomon arfp.set(pipelineBuilder); 14848af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon } 1485d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt 1486d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt SkMatrix invert; 14878059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt if (!viewMatrix.invert(&invert)) { 14888af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon return false; 14898af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon } 1490d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt 14918dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel pipelineBuilder->addCoverageProcessor(effect)->unref(); 14928af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon SkRect bounds = outer->getBounds(); 14938af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon if (applyAA) { 14948af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 14958af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon } 14968dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel target->drawRect(pipelineBuilder, color, SkMatrix::I(), bounds, NULL, &invert); 14978af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon return true; 14980a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org} 14990a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 150076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt/////////////////////////////////////////////////////////////////////////////////////////////////// 150176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 150276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittclass RRectCircleRendererBatch : public GrBatch { 150376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittpublic: 150476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct Geometry { 150576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 150676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix fViewMatrix; 150776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fInnerRadius; 150876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fOuterRadius; 150976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fStroke; 1510bc227140ffea6eb15e2e8b147eb6d8ec6228d95aegdaniel SkRect fDevBounds; 151176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 151276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1513ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon static GrBatch* Create(const Geometry& geometry) { 1514ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon return SkNEW_ARGS(RRectCircleRendererBatch, (geometry)); 151576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 151676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 151736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "RRectCircleBatch"; } 151876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 151936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 152076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 152176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setKnownFourComponents(fGeoData[0].fColor); 152276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 152336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 152476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setUnknownSingleComponent(); 152576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 152676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 152736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(const GrPipelineInfo& init) override { 152876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Handle any color overrides 152976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (init.fColorIgnored) { 153076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 153176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } else if (GrColor_ILLEGAL != init.fOverrideColor) { 153276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = init.fOverrideColor; 153376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 153476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 153576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // setup batch properties 153676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColorIgnored = init.fColorIgnored; 153776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColor = fGeoData[0].fColor; 153876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fStroke = fGeoData[0].fStroke; 153976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 154076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fCoverageIgnored = init.fCoverageIgnored; 154176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 154276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 154336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 154476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // reset to device coordinates 154576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix invert; 154676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (!this->viewMatrix().invert(&invert)) { 154776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkDebugf("Failed to invert\n"); 154876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return; 154976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 155076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 155176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 155276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkAutoTUnref<GrGeometryProcessor> gp(CircleEdgeEffect::Create(this->color(), 155376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->stroke(), 155476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt invert)); 155576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 155676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt batchTarget->initDraw(gp, pipeline); 155776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 155876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO this is hacky, but the only way we have to initialize the GP is to use the 155976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch 156076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // everywhere we can remove this nastiness 156176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrPipelineInfo init; 156276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fColorIgnored = fBatch.fColorIgnored; 156376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fOverrideColor = GrColor_ILLEGAL; 156476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fCoverageIgnored = fBatch.fCoverageIgnored; 156576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fUsesLocalCoords = this->usesLocalCoords(); 156676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt gp->initBatchTracker(batchTarget->currentBatchTracker(), init); 156776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 156876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 156976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 157076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(vertexStride == sizeof(CircleVertex)); 157176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1572b5238a7571c243ba4a154a62575570c3078b3741bsalomon // drop out the middle quad if we're stroked 1573b5238a7571c243ba4a154a62575570c3078b3741bsalomon int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect; 1574ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon SkAutoTUnref<const GrIndexBuffer> indexBuffer( 1575ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider())); 157676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1577b5238a7571c243ba4a154a62575570c3078b3741bsalomon InstancedHelper helper; 1578b5238a7571c243ba4a154a62575570c3078b3741bsalomon CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchTarget, 1579b5238a7571c243ba4a154a62575570c3078b3741bsalomon kTriangles_GrPrimitiveType, vertexStride, indexBuffer, kVertsPerRRect, 1580b5238a7571c243ba4a154a62575570c3078b3741bsalomon indicesPerInstance, instanceCount)); 1581b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts || !indexBuffer) { 15824b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate vertices\n"); 15834b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 15844b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 15854b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 158676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 158776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt Geometry& args = fGeoData[i]; 158876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 158976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar outerRadius = args.fOuterRadius; 159076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1591bc227140ffea6eb15e2e8b147eb6d8ec6228d95aegdaniel const SkRect& bounds = args.fDevBounds; 159276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 159376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yCoords[4] = { 159476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fTop, 159576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fTop + outerRadius, 159676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fBottom - outerRadius, 159776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fBottom 159876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 159976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 160076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yOuterRadii[4] = {-1, 0, 0, 1 }; 160176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // The inner radius in the vertex data must be specified in normalized space. 160276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar innerRadius = args.fInnerRadius / args.fOuterRadius; 160376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < 4; ++i) { 160476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); 160576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(-1, yOuterRadii[i]); 160676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadius = outerRadius; 160776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadius = innerRadius; 160876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 160976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 161076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fLeft + outerRadius, yCoords[i]); 161176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(0, yOuterRadii[i]); 161276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadius = outerRadius; 161376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadius = innerRadius; 161476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 161576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 161676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fRight - outerRadius, yCoords[i]); 161776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(0, yOuterRadii[i]); 161876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadius = outerRadius; 161976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadius = innerRadius; 162076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 162176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 162276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); 162376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(1, yOuterRadii[i]); 162476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadius = outerRadius; 162576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadius = innerRadius; 162676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 162776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 162876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 162976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1630e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon helper.issueDraw(batchTarget); 163176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 163276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 163376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 163476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 163576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittprivate: 1636ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon RRectCircleRendererBatch(const Geometry& geometry) { 163776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->initClassID<RRectCircleRendererBatch>(); 163876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back(geometry); 163999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 164099c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->setBounds(geometry.fDevBounds); 164176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 164276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 164336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onCombineIfPossible(GrBatch* t) override { 164476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>(); 164576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 164676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO use vertex color to avoid breaking batches 164776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->color() != that->color()) { 164876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 164976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 165076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 165176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->stroke() != that->stroke()) { 165276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 165376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 165476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 165576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 165676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 165776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 165876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 165976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 166076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 166199c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 166276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 166376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 166476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 166576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor color() const { return fBatch.fColor; } 166676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 166776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 166876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool stroke() const { return fBatch.fStroke; } 166976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 167076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct BatchTracker { 167176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 167276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fStroke; 167376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fUsesLocalCoords; 167476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fColorIgnored; 167576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fCoverageIgnored; 167676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 167776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 167876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt BatchTracker fBatch; 167976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 168076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 168176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 168276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittclass RRectEllipseRendererBatch : public GrBatch { 168376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittpublic: 168476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct Geometry { 168576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 168676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix fViewMatrix; 168776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fXRadius; 168876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fYRadius; 168976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fInnerXRadius; 169076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar fInnerYRadius; 169176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fStroke; 1692bc227140ffea6eb15e2e8b147eb6d8ec6228d95aegdaniel SkRect fDevBounds; 169376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 169476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1695ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon static GrBatch* Create(const Geometry& geometry) { 1696ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry)); 169776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 169876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 169936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "RRectEllipseRendererBatch"; } 170076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 170136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 170276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // When this is called on a batch, there is only one geometry bundle 170376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setKnownFourComponents(fGeoData[0].fColor); 170476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 170536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 170676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt out->setUnknownSingleComponent(); 170776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 170876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 170936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void initBatchTracker(const GrPipelineInfo& init) override { 171076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Handle any color overrides 171176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (init.fColorIgnored) { 171276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = GrColor_ILLEGAL; 171376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } else if (GrColor_ILLEGAL != init.fOverrideColor) { 171476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData[0].fColor = init.fOverrideColor; 171576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 171676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 171776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // setup batch properties 171876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColorIgnored = init.fColorIgnored; 171976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fColor = fGeoData[0].fColor; 172076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fStroke = fGeoData[0].fStroke; 172176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fUsesLocalCoords = init.fUsesLocalCoords; 172276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fBatch.fCoverageIgnored = init.fCoverageIgnored; 172376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 172476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 172536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { 172676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // reset to device coordinates 172776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkMatrix invert; 172876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (!this->viewMatrix().invert(&invert)) { 172976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkDebugf("Failed to invert\n"); 173076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return; 173176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 173276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 173376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Setup geometry processor 173476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkAutoTUnref<GrGeometryProcessor> gp(EllipseEdgeEffect::Create(this->color(), 173576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->stroke(), 173676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt invert)); 173776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 173876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt batchTarget->initDraw(gp, pipeline); 173976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 174076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO this is hacky, but the only way we have to initialize the GP is to use the 174176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch 174276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // everywhere we can remove this nastiness 174376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrPipelineInfo init; 174476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fColorIgnored = fBatch.fColorIgnored; 174576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fOverrideColor = GrColor_ILLEGAL; 174676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fCoverageIgnored = fBatch.fCoverageIgnored; 174776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt init.fUsesLocalCoords = this->usesLocalCoords(); 174876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt gp->initBatchTracker(batchTarget->currentBatchTracker(), init); 174976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 175076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt int instanceCount = fGeoData.count(); 175176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt size_t vertexStride = gp->getVertexStride(); 175276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(vertexStride == sizeof(EllipseVertex)); 175376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1754b5238a7571c243ba4a154a62575570c3078b3741bsalomon // drop out the middle quad if we're stroked 1755b5238a7571c243ba4a154a62575570c3078b3741bsalomon int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndicesPerRRect; 1756ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon SkAutoTUnref<const GrIndexBuffer> indexBuffer( 1757ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider())); 175876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1759b5238a7571c243ba4a154a62575570c3078b3741bsalomon InstancedHelper helper; 1760b5238a7571c243ba4a154a62575570c3078b3741bsalomon EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( 1761b5238a7571c243ba4a154a62575570c3078b3741bsalomon helper.init(batchTarget, kTriangles_GrPrimitiveType, vertexStride, indexBuffer, 1762b5238a7571c243ba4a154a62575570c3078b3741bsalomon kVertsPerRRect, indicesPerInstance, instanceCount)); 1763b5238a7571c243ba4a154a62575570c3078b3741bsalomon if (!verts || !indexBuffer) { 17644b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt SkDebugf("Could not allocate vertices\n"); 17654b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt return; 17664b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt } 17674b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt 176876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < instanceCount; i++) { 176976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt Geometry& args = fGeoData[i]; 177076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 177176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Compute the reciprocals of the radii here to save time in the shader 177276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar xRadRecip = SkScalarInvert(args.fXRadius); 177376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yRadRecip = SkScalarInvert(args.fYRadius); 177476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius); 177576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius); 177676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 177776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // Extend the radii out half a pixel to antialias. 177876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar xOuterRadius = args.fXRadius + SK_ScalarHalf; 177976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yOuterRadius = args.fYRadius + SK_ScalarHalf; 178076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 1781bc227140ffea6eb15e2e8b147eb6d8ec6228d95aegdaniel const SkRect& bounds = args.fDevBounds; 178276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 178376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yCoords[4] = { 178476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fTop, 178576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fTop + yOuterRadius, 178676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fBottom - yOuterRadius, 178776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bounds.fBottom 178876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 178976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkScalar yOuterOffsets[4] = { 179076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt yOuterRadius, 179176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SK_ScalarNearlyZero, // we're using inversesqrt() in shader, so can't be exactly 0 179276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SK_ScalarNearlyZero, 179376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt yOuterRadius 179476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 179576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 179676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt for (int i = 0; i < 4; ++i) { 179776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]); 179876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); 179976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 180076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 180176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 180276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 180376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fLeft + xOuterRadius, yCoords[i]); 180476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i]); 180576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 180676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 180776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 180876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 180976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fRight - xOuterRadius, yCoords[i]); 181076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(SK_ScalarNearlyZero, yOuterOffsets[i]); 181176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 181276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 181376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 181476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 181576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); 181676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); 181776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); 181876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip); 181976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt verts++; 182076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 182176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 1822e64eb570a5b9480bc24d0656ccabcff1ab13a229bsalomon helper.issueDraw(batchTarget); 182376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 182476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 182576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 182676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 182776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualittprivate: 1828ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon RRectEllipseRendererBatch(const Geometry& geometry) { 182976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt this->initClassID<RRectEllipseRendererBatch>(); 183076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back(geometry); 183199c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt 183299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->setBounds(geometry.fDevBounds); 183376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 183476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 183536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onCombineIfPossible(GrBatch* t) override { 183676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt RRectEllipseRendererBatch* that = t->cast<RRectEllipseRendererBatch>(); 183776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 183876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt // TODO use vertex color to avoid breaking batches 183976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->color() != that->color()) { 184076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 184176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 184276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 184376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->stroke() != that->stroke()) { 184476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 184576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 184676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 184776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); 184876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) { 184976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return false; 185076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 185176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 185276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin()); 185399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt this->joinBounds(that->bounds()); 185476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt return true; 185576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt } 185676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 185776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor color() const { return fBatch.fColor; } 185876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } 185976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } 186076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool stroke() const { return fBatch.fStroke; } 186176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 186276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt struct BatchTracker { 186376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt GrColor fColor; 186476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fStroke; 186576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fUsesLocalCoords; 186676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fColorIgnored; 186776e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt bool fCoverageIgnored; 186876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt }; 186976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 187076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt BatchTracker fBatch; 187176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt SkSTArray<1, Geometry, true> fGeoData; 187276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt}; 187376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 18743e708c53f79a04b588b6ca8e535e61f986d80b47joshualittstatic GrBatch* create_rrect_batch(GrColor color, 18753e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkMatrix& viewMatrix, 18763e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRRect& rrect, 1877d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt const SkStrokeRec& stroke) { 18783e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkASSERT(viewMatrix.rectStaysRect()); 18793e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkASSERT(rrect.isSimple()); 18803e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkASSERT(!rrect.isOval()); 18813e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 18823e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt // RRect batchs only handle simple, but not too simple, rrects 1883f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // do any matrix crunching before we reset the draw state for device coords 1884f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org const SkRect& rrectBounds = rrect.getBounds(); 1885d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt SkRect bounds; 1886d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt viewMatrix.mapRect(&bounds, rrectBounds); 1887f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1888f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkVector radii = rrect.getSimpleRadii(); 18898059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX + 18908059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMSkewY]*radii.fY); 18918059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX + 18928059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMScaleY]*radii.fY); 18936bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 1894f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkStrokeRec::Style style = stroke.getStyle(); 1895f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1896f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // do (potentially) anisotropic mapping of stroke 1897f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkVector scaledStroke; 1898f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkScalar strokeWidth = stroke.getWidth(); 1899f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 19000a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 19010a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org SkStrokeRec::kHairline_Style == style; 19020a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 19030a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 19040a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (hasStroke) { 19050a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (SkStrokeRec::kHairline_Style == style) { 19060a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org scaledStroke.set(1, 1); 19070a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } else { 19088059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMScaleX] + 19098059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMSkewY])); 19108059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSkewX] + 19118059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt viewMatrix[SkMatrix::kMScaleY])); 19120a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 19130a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 19140a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // if half of strokewidth is greater than radius, we don't handle that right now 19150a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStroke.fY > yRadius) { 19163e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return NULL; 19170a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 19180a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org } 19190a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org 19200a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // The way the effect interpolates the offset-to-ellipse/circle-center attribute only works on 19210a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner rect of the nine- 19220a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // patch will have fractional coverage. This only matters when the interior is actually filled. 19230a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // We could consider falling back to rect rendering here, since a tiny radius is 19240a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org // indistinguishable from a square corner. 19250a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { 19263e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return NULL; 1927f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1928f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1929f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // if the corners are circles, use the circle renderer 19300a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius) { 1931f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkScalar innerRadius = 0.0f; 1932f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkScalar outerRadius = xRadius; 1933f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkScalar halfWidth = 0; 19340a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (hasStroke) { 1935f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org if (SkScalarNearlyZero(scaledStroke.fX)) { 1936f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org halfWidth = SK_ScalarHalf; 1937f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else { 1938f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org halfWidth = SkScalarHalf(scaledStroke.fX); 1939f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 19402cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 19410a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (isStrokeOnly) { 19426bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org innerRadius = xRadius - halfWidth; 1943f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1944f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org outerRadius += halfWidth; 1945d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt bounds.outset(halfWidth, halfWidth); 1946f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 19472cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 19480a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org isStrokeOnly = (isStrokeOnly && innerRadius >= 0); 1949cefde6e5783bcce27369216e5e4ee5c7eed02e26commit-bot@chromium.org 1950f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // The radii are outset for two reasons. First, it allows the shader to simply perform 1951ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon // simpler computation because the computed alpha is zero, rather than 50%, at the radius. 1952ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon // Second, the outer radius is used to compute the verts of the bounding box that is 1953ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon // rendered and the outset ensures the box will cover all partially covered by the rrect 1954ce1c8869cf5e37753f9c8193314d93bff897d014bsalomon // corners. 1955f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org outerRadius += SK_ScalarHalf; 1956f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org innerRadius -= SK_ScalarHalf; 19572cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 1958f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // Expand the rect so all the pixels will be captured. 1959d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 19602cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 196176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt RRectCircleRendererBatch::Geometry geometry; 196276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fViewMatrix = viewMatrix; 196376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fColor = color; 196476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fInnerRadius = innerRadius; 196576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fOuterRadius = outerRadius; 196676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fStroke = isStrokeOnly; 1967d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt geometry.fDevBounds = bounds; 19682cf444f7040614b43af67e368f3aa636ebeaa45askia.committer@gmail.com 1969ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon return RRectCircleRendererBatch::Create(geometry); 19706bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // otherwise we use the ellipse renderer 1971f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else { 1972f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkScalar innerXRadius = 0.0f; 1973f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org SkScalar innerYRadius = 0.0f; 19740a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (hasStroke) { 1975f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org if (SkScalarNearlyZero(scaledStroke.length())) { 1976f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); 1977f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } else { 19786bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org scaledStroke.scale(SK_ScalarHalf); 19796bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } 19806bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 19816bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // we only handle thick strokes for near-circular ellipses 19828be02fc2a72ae69a9142de68a483edf378aff1c8skia.committer@gmail.com if (scaledStroke.length() > SK_ScalarHalf && 19836bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) { 19843e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return NULL; 19856bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org } 19866bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 19876bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org // we don't handle it if curvature of the stroke is less than curvature of the ellipse 19886bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY)*xRadius || 19896bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX)*yRadius) { 19903e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return NULL; 1991f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 1992f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 1993f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // this is legit only if scale & translation (which should be the case at the moment) 19940a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org if (isStrokeOnly) { 19956bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org innerXRadius = xRadius - scaledStroke.fX; 19966bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org innerYRadius = yRadius - scaledStroke.fY; 1997f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 19986bb3efc4db8e4e348c6ef6033ffaf8410a82eae5commit-bot@chromium.org 1999f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org xRadius += scaledStroke.fX; 2000f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org yRadius += scaledStroke.fY; 2001d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt bounds.outset(scaledStroke.fX, scaledStroke.fY); 2002f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 2003f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 20040a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); 2005cefde6e5783bcce27369216e5e4ee5c7eed02e26commit-bot@chromium.org 2006f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org // Expand the rect so all the pixels will be captured. 2007d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 2008f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org 200976e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt RRectEllipseRendererBatch::Geometry geometry; 201076e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fViewMatrix = viewMatrix; 201176e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fColor = color; 201276e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fXRadius = xRadius; 201376e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fYRadius = yRadius; 201476e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fInnerXRadius = innerXRadius; 201576e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fInnerYRadius = innerYRadius; 201676e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt geometry.fStroke = isStrokeOnly; 2017d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt geometry.fDevBounds = bounds; 201876e7fb6cbaa0994778cc4cf48bfe5e70bae59821joshualitt 2019ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon return RRectEllipseRendererBatch::Create(geometry); 2020f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org } 20213e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 20223e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20233e708c53f79a04b588b6ca8e535e61f986d80b47joshualittbool GrOvalRenderer::drawRRect(GrDrawTarget* target, 20243e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrPipelineBuilder* pipelineBuilder, 20253e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color, 20263e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkMatrix& viewMatrix, 20273e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useAA, 20283e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRRect& rrect, 20293e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkStrokeRec& stroke) { 20303e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt if (rrect.isOval()) { 20313e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA, rrect.getBounds(), 20323e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt stroke); 20333e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt } 20343e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20353e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisampled(); 20363e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20373e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt // only anti-aliased rrects for now 20383e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt if (!useCoverageAA) { 20393e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return false; 20403e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt } 20413e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20423e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { 20433e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return false; 20443e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt } 20453e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 2046d96a67bcb196aa4f73ff773bd45810a94ca872d8joshualitt SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, stroke)); 20473e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt if (!batch) { 20483e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return false; 20493e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt } 20503e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 205199c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt target->drawBatch(pipelineBuilder, batch); 2052f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org return true; 2053f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org} 20543e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20553e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt/////////////////////////////////////////////////////////////////////////////////////////////////// 20563e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20573e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt#ifdef GR_TEST_UTILS 20583e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20593e708c53f79a04b588b6ca8e535e61f986d80b47joshualittBATCH_TEST_DEFINE(CircleBatch) { 20603e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkMatrix viewMatrix = GrTest::TestMatrix(random); 20613e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color = GrRandomColor(random); 20623e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA = random->nextBool(); 20636c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt SkRect circle = GrTest::TestSquare(random); 206421279c7ada1e47e8bfc6375f67768c8eedffb680joshualitt return create_circle_batch(color, viewMatrix, useCoverageAA, circle, 206521279c7ada1e47e8bfc6375f67768c8eedffb680joshualitt GrTest::TestStrokeRec(random)); 20663e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 20673e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20683e708c53f79a04b588b6ca8e535e61f986d80b47joshualittBATCH_TEST_DEFINE(EllipseBatch) { 20693e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); 20703e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color = GrRandomColor(random); 20716c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt SkRect ellipse = GrTest::TestSquare(random); 20726c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt return create_ellipse_batch(color, viewMatrix, true, ellipse, 207321279c7ada1e47e8bfc6375f67768c8eedffb680joshualitt GrTest::TestStrokeRec(random)); 20743e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 20753e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20763e708c53f79a04b588b6ca8e535e61f986d80b47joshualittBATCH_TEST_DEFINE(DIEllipseBatch) { 20773e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkMatrix viewMatrix = GrTest::TestMatrix(random); 20783e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color = GrRandomColor(random); 20793e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt bool useCoverageAA = random->nextBool(); 20806c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualitt SkRect ellipse = GrTest::TestSquare(random); 20813e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, 208221279c7ada1e47e8bfc6375f67768c8eedffb680joshualitt GrTest::TestStrokeRec(random)); 20833e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 20843e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20853e708c53f79a04b588b6ca8e535e61f986d80b47joshualittBATCH_TEST_DEFINE(RRectBatch) { 20863e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); 20873e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt GrColor color = GrRandomColor(random); 20883e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt const SkRRect& rrect = GrTest::TestRRectSimple(random); 208921279c7ada1e47e8bfc6375f67768c8eedffb680joshualitt return create_rrect_batch(color, viewMatrix, rrect, GrTest::TestStrokeRec(random)); 20903e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt} 20913e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt 20923e708c53f79a04b588b6ca8e535e61f986d80b47joshualitt#endif 2093