1c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org/* 2c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org * Copyright 2014 Google Inc. 3c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org * 4c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be 5c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org * found in the LICENSE file. 6c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org */ 7c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 8c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org#include "GrConvexPolyEffect.h" 9605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdaniel#include "GrInvariantOutput.h" 10eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "SkPath.h" 11b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "gl/GrGLProcessor.h" 12c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org#include "gl/GrGLSL.h" 13eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt#include "gl/builders/GrGLProgramBuilder.h" 14c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 15f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 16b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass AARectEffect : public GrFragmentProcessor { 17f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgpublic: 18f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const SkRect& getRect() const { return fRect; } 19f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 20b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt static GrFragmentProcessor* Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) { 2155fad7af61c21d502acb9891d631e8aa29e3628cbsalomon return SkNEW_ARGS(AARectEffect, (edgeType, rect)); 22f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 23f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 24b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; } 25d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org 2636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const char* name() const override { return "AARect"; } 27eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 28cfc18867d982119d9dc2888bf09f1093012daaddjvanverth void getGLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override; 29eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 3036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein GrGLFragmentProcessor* createGLInstance() const override; 31f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 32f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgprivate: 33eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt AARectEffect(GrPrimitiveEdgeType edgeType, const SkRect& rect) 34eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt : fRect(rect), fEdgeType(edgeType) { 35eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<AARectEffect>(); 36f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org this->setWillReadFragmentPosition(); 37f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 38f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 3936352bf5e38f45a70ee4f4fc132a38048d38206dmtklein bool onIsEqual(const GrFragmentProcessor& other) const override { 4049586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const AARectEffect& aare = other.cast<AARectEffect>(); 41f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org return fRect == aare.fRect; 42f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 43f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 4436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 451a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel if (fRect.isEmpty()) { 461a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel // An empty rect will have no coverage anywhere. 4756995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt inout->mulByKnownSingleComponent(0); 481a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel } else { 4956995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt inout->mulByUnknownSingleComponent(); 501a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel } 511a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel } 521a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 53b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkRect fRect; 54b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType fEdgeType; 55d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org 56b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrFragmentProcessor INHERITED; 57f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 58b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 59f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 60f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org}; 61f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 62b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(AARectEffect); 63f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 64b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* AARectEffect::TestCreate(SkRandom* random, 65b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 66b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps& caps, 67b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture*[]) { 68f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(), 69f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org random->nextSScalar1(), 70f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org random->nextSScalar1(), 71f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org random->nextSScalar1()); 72b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* fp; 73cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org do { 74b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>(random->nextULessThan( 75b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt kGrProcessorEdgeTypeCnt)); 76cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org 77b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fp = AARectEffect::Create(edgeType, rect); 78b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt } while (NULL == fp); 79b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return fp; 80f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 81f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 82f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 83f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 84b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GLAARectEffect : public GrGLFragmentProcessor { 85f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgpublic: 86eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLAARectEffect(const GrProcessor&); 87f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 881598899975ecc85b003a59740b588d1ddbcedb09joshualitt virtual void emitCode(GrGLFPBuilder* builder, 89b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 90f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char* outputColor, 91f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char* inputColor, 92f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const TransformedCoordsArray&, 9336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const TextureSamplerArray&) override; 94f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 95cfc18867d982119d9dc2888bf09f1093012daaddjvanverth static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*); 96f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 9736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void setData(const GrGLProgramDataManager&, const GrProcessor&) override; 98f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 99f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.orgprivate: 1007510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fRectUniform; 1017510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkRect fPrevRect; 102b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 103f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org}; 104f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 105eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGLAARectEffect::GLAARectEffect(const GrProcessor& effect) { 106f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org fPrevRect.fLeft = SK_ScalarNaN; 107f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 108f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 1091598899975ecc85b003a59740b588d1ddbcedb09joshualittvoid GLAARectEffect::emitCode(GrGLFPBuilder* builder, 110b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 111f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char* outputColor, 112f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char* inputColor, 113f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const TransformedCoordsArray&, 114f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const TextureSamplerArray& samplers) { 115b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const AARectEffect& aare = fp.cast<AARectEffect>(); 116f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const char *rectName; 117d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), 118d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // respectively. 11930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fRectUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, 120f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org kVec4f_GrSLType, 121422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon kDefault_GrSLPrecision, 122f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org "rect", 123f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org &rectName); 12430ba436f04e61d4505fb854d5fc56079636e0788joshualitt 12529bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 12630ba436f04e61d4505fb854d5fc56079636e0788joshualitt const char* fragmentPos = fsBuilder->fragmentPosition(); 127b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsAA(aare.getEdgeType())) { 128d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // The amount of coverage removed in x and y by the edges is computed as a pair of negative 129d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // numbers, xSub and ySub. 13030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat xSub, ySub;\n"); 13130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName); 13230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos); 13330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName); 13430ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos); 135d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // Now compute coverage in x and y and multiply them to get the fraction of the pixel 136d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org // covered. 13730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); 138d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org } else { 13930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\tfloat alpha = 1.0;\n"); 1407f14c9bbf1954a88226a0b56f1abb1a17f31534crobertphillips fsBuilder->codeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); 1417f14c9bbf1954a88226a0b56f1abb1a17f31534crobertphillips fsBuilder->codeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); 1427f14c9bbf1954a88226a0b56f1abb1a17f31534crobertphillips fsBuilder->codeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); 1437f14c9bbf1954a88226a0b56f1abb1a17f31534crobertphillips fsBuilder->codeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); 144d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org } 145f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 146b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsInverseFill(aare.getEdgeType())) { 14730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\talpha = 1.0 - alpha;\n"); 148d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org } 14930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t\t%s = %s;\n", outputColor, 150f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); 151f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 152f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 153b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GLAARectEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& processor) { 154b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const AARectEffect& aare = processor.cast<AARectEffect>(); 155f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org const SkRect& rect = aare.getRect(); 156f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org if (rect != fPrevRect) { 1577f14c9bbf1954a88226a0b56f1abb1a17f31534crobertphillips pdman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, 1587f14c9bbf1954a88226a0b56f1abb1a17f31534crobertphillips rect.fRight - 0.5f, rect.fBottom - 0.5f); 159f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org fPrevRect = rect; 160f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org } 161f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 162f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 163cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GLAARectEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&, 164b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 165b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const AARectEffect& aare = processor.cast<AARectEffect>(); 16663e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(aare.getEdgeType()); 167d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org} 168d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org 169cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid AARectEffect::getGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { 170eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GLAARectEffect::GenKey(*this, caps, b); 171eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 172eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 173eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLFragmentProcessor* AARectEffect::createGLInstance() const { 174eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GLAARectEffect, (*this)); 175f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 176f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 177f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 178f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 179b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrGLConvexPolyEffect : public GrGLFragmentProcessor { 180c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.orgpublic: 181eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLConvexPolyEffect(const GrProcessor&); 182c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 1831598899975ecc85b003a59740b588d1ddbcedb09joshualitt virtual void emitCode(GrGLFPBuilder* builder, 184b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 185c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char* outputColor, 186c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char* inputColor, 187c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const TransformedCoordsArray&, 18836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein const TextureSamplerArray&) override; 189c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 190cfc18867d982119d9dc2888bf09f1093012daaddjvanverth static inline void GenKey(const GrProcessor&, const GrGLSLCaps&, GrProcessorKeyBuilder*); 191c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 19236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein void setData(const GrGLProgramDataManager&, const GrProcessor&) override; 193c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 194c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.orgprivate: 1957510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen GrGLProgramDataManager::UniformHandle fEdgeUniform; 1967510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen SkScalar fPrevEdges[3 * GrConvexPolyEffect::kMaxEdges]; 197b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrGLFragmentProcessor INHERITED; 198c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org}; 199c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 200eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLConvexPolyEffect::GrGLConvexPolyEffect(const GrProcessor&) { 201c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org fPrevEdges[0] = SK_ScalarNaN; 202c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 203c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 2041598899975ecc85b003a59740b588d1ddbcedb09joshualittvoid GrGLConvexPolyEffect::emitCode(GrGLFPBuilder* builder, 205b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrFragmentProcessor& fp, 206c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char* outputColor, 207c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char* inputColor, 208c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const TransformedCoordsArray&, 209c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const TextureSamplerArray& samplers) { 210b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrConvexPolyEffect& cpe = fp.cast<GrConvexPolyEffect>(); 211c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 212c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org const char *edgeArrayName; 21330ba436f04e61d4505fb854d5fc56079636e0788joshualitt fEdgeUniform = builder->addUniformArray(GrGLProgramBuilder::kFragment_Visibility, 214c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org kVec3f_GrSLType, 215422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon kDefault_GrSLPrecision, 216422f56f6e51c2f6a6ab425573b4d790f0157f883bsalomon "edges", 217c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org cpe.getEdgeCount(), 218c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org &edgeArrayName); 21929bee0fe657fabf7c396502b69c9167fba13eaaaegdaniel GrGLFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); 22030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat alpha = 1.0;\n"); 22130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tfloat edge;\n"); 22230ba436f04e61d4505fb854d5fc56079636e0788joshualitt const char* fragmentPos = fsBuilder->fragmentPosition(); 223c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org for (int i = 0; i < cpe.getEdgeCount(); ++i) { 2247f14c9bbf1954a88226a0b56f1abb1a17f31534crobertphillips fsBuilder->codeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n", 225c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edgeArrayName, i, fragmentPos, fragmentPos); 226b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsAA(cpe.getEdgeType())) { 22730ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); 228cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org } else { 22930ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); 230c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 23130ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\talpha *= edge;\n"); 232c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 233c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 2346dee8759ab8c90dcffd76f114eec333405fd176ecommit-bot@chromium.org // Woe is me. See skbug.com/2149. 2356dee8759ab8c90dcffd76f114eec333405fd176ecommit-bot@chromium.org if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) { 23630ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n"); 2376dee8759ab8c90dcffd76f114eec333405fd176ecommit-bot@chromium.org } 238d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org 239b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (GrProcessorEdgeTypeIsInverseFill(cpe.getEdgeType())) { 24030ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppend("\talpha = 1.0 - alpha;\n"); 241d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org } 24230ba436f04e61d4505fb854d5fc56079636e0788joshualitt fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, 243c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); 244c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 245c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 246b0a8a377f832c59cee939ad721e1f87d378b7142joshualittvoid GrGLConvexPolyEffect::setData(const GrGLProgramDataManager& pdman, const GrProcessor& effect) { 24749586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrConvexPolyEffect& cpe = effect.cast<GrConvexPolyEffect>(); 248c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org size_t byteSize = 3 * cpe.getEdgeCount() * sizeof(SkScalar); 249c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (0 != memcmp(fPrevEdges, cpe.getEdges(), byteSize)) { 2507510b224e52b9518a8ddf7418db0e9c258f79539kkinnunen pdman.set3fv(fEdgeUniform, cpe.getEdgeCount(), cpe.getEdges()); 251c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org memcpy(fPrevEdges, cpe.getEdges(), byteSize); 252c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 253c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 254c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 255cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GrGLConvexPolyEffect::GenKey(const GrProcessor& processor, const GrGLSLCaps&, 256b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessorKeyBuilder* b) { 257b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrConvexPolyEffect& cpe = processor.cast<GrConvexPolyEffect>(); 258b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GR_STATIC_ASSERT(kGrProcessorEdgeTypeCnt <= 8); 25963e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon uint32_t key = (cpe.getEdgeCount() << 3) | cpe.getEdgeType(); 26063e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon b->add32(key); 261c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 262c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 263c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 264c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 265b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType type, const SkPath& path, 266b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const SkVector* offset) { 267b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (kHairlineAA_GrProcessorEdgeType == type) { 268cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org return NULL; 269cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org } 270c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (path.getSegmentMasks() != SkPath::kLine_SegmentMask || 271cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org !path.isConvex()) { 272c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org return NULL; 273c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 274c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 275c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (path.countPoints() > kMaxEdges) { 276c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org return NULL; 277c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 278c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 279c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkPoint pts[kMaxEdges]; 280c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkScalar edges[3 * kMaxEdges]; 281c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 282c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkPath::Direction dir; 283c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkAssertResult(path.cheapComputeDirection(&dir)); 284c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 285b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org SkVector t; 286b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org if (NULL == offset) { 287b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org t.set(0, 0); 288b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org } else { 289b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org t = *offset; 290b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org } 291b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org 292c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org int count = path.getPoints(pts, kMaxEdges); 293c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org int n = 0; 294c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org for (int lastPt = count - 1, i = 0; i < count; lastPt = i++) { 295c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (pts[lastPt] != pts[i]) { 296c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkVector v = pts[i] - pts[lastPt]; 297c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org v.normalize(); 298c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org if (SkPath::kCCW_Direction == dir) { 299c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[3 * n] = v.fY; 300c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[3 * n + 1] = -v.fX; 301c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } else { 302c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[3 * n] = -v.fY; 303c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[3 * n + 1] = v.fX; 304c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 305b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org SkPoint p = pts[i] + t; 306b21fac156d9287d6c0cfd446d707c4c7be6fae6ecommit-bot@chromium.org edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY); 307c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org ++n; 308c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 309c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 310cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org if (path.isInverseFillType()) { 311b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt type = GrInvertProcessorEdgeType(type); 312cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org } 313c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org return Create(type, n, edges); 314c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 315c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 316b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) { 317b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt if (kHairlineAA_GrProcessorEdgeType == edgeType){ 318cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org return NULL; 319cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org } 320d85f32ca40475fb246dd8ca93abaf1c3db0389e1commit-bot@chromium.org return AARectEffect::Create(edgeType, rect); 321f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org} 322f0539800165314f8bebd8a5ab765ec35012f1b03commit-bot@chromium.org 323c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.orgGrConvexPolyEffect::~GrConvexPolyEffect() {} 324c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 325605dd0fbce9dbb2a0d3313e13e161f2bd54870d7egdanielvoid GrConvexPolyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) const { 32656995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt inout->mulByUnknownSingleComponent(); 327c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 328c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 329cfc18867d982119d9dc2888bf09f1093012daaddjvanverthvoid GrConvexPolyEffect::getGLProcessorKey(const GrGLSLCaps& caps, 330eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrProcessorKeyBuilder* b) const { 331eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrGLConvexPolyEffect::GenKey(*this, caps, b); 332eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt} 333eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 334eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittGrGLFragmentProcessor* GrConvexPolyEffect::createGLInstance() const { 335eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt return SkNEW_ARGS(GrGLConvexPolyEffect, (*this)); 336c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 337c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 338b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrConvexPolyEffect::GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[]) 339c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org : fEdgeType(edgeType) 340c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org , fEdgeCount(n) { 341eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt this->initClassID<GrConvexPolyEffect>(); 342c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org // Factory function should have already ensured this. 343c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkASSERT(n <= kMaxEdges); 344c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org memcpy(fEdges, edges, 3 * n * sizeof(SkScalar)); 345c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org // Outset the edges by 0.5 so that a pixel with center on an edge is 50% covered in the AA case 346c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org // and 100% covered in the non-AA case. 347c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org for (int i = 0; i < n; ++i) { 348c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org fEdges[3 * i + 2] += SK_ScalarHalf; 349c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 350c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org this->setWillReadFragmentPosition(); 351c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 352c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 3530e08fc17e4718f7ce4e38f793695896473e96948bsalomonbool GrConvexPolyEffect::onIsEqual(const GrFragmentProcessor& other) const { 35449586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt const GrConvexPolyEffect& cpe = other.cast<GrConvexPolyEffect>(); 355c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org // ignore the fact that 0 == -0 and just use memcmp. 356c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org return (cpe.fEdgeType == fEdgeType && cpe.fEdgeCount == fEdgeCount && 357c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 0 == memcmp(cpe.fEdges, fEdges, 3 * fEdgeCount * sizeof(SkScalar))); 358c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 359c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 360c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org////////////////////////////////////////////////////////////////////////////// 361c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 362b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrConvexPolyEffect); 363c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 364b0a8a377f832c59cee939ad721e1f87d378b7142joshualittGrFragmentProcessor* GrConvexPolyEffect::TestCreate(SkRandom* random, 365b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrContext*, 366b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt const GrDrawTargetCaps& caps, 367b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTexture*[]) { 36865ee5f424cb4dabd453268902c00086605d77c1dcommit-bot@chromium.org int count = random->nextULessThan(kMaxEdges) + 1; 369c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org SkScalar edges[kMaxEdges * 3]; 370c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org for (int i = 0; i < 3 * count; ++i) { 371c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org edges[i] = random->nextSScalar1(); 372c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org } 373c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org 374b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor* fp; 375cabf4b2f3664b98c1084fbb94a999af15ddfb52dcommit-bot@chromium.org do { 376b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>( 377b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt random->nextULessThan(kGrProcessorEdgeTypeCnt)); 378b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt fp = GrConvexPolyEffect::Create(edgeType, count, edges); 379b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt } while (NULL == fp); 380b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt return fp; 381c3fe54975daf6274103bcfefe5ed2e7af8d0170acommit-bot@chromium.org} 382