18072caa80384292858d31ae34b7e19768875866bjoshualitt/* 28072caa80384292858d31ae34b7e19768875866bjoshualitt * Copyright 2013 Google Inc. 38072caa80384292858d31ae34b7e19768875866bjoshualitt * 48072caa80384292858d31ae34b7e19768875866bjoshualitt * Use of this source code is governed by a BSD-style license that can be 58072caa80384292858d31ae34b7e19768875866bjoshualitt * found in the LICENSE file. 68072caa80384292858d31ae34b7e19768875866bjoshualitt */ 78072caa80384292858d31ae34b7e19768875866bjoshualitt 88072caa80384292858d31ae34b7e19768875866bjoshualitt#ifndef GrPrimitiveProcessor_DEFINED 98072caa80384292858d31ae34b7e19768875866bjoshualitt#define GrPrimitiveProcessor_DEFINED 108072caa80384292858d31ae34b7e19768875866bjoshualitt 118072caa80384292858d31ae34b7e19768875866bjoshualitt#include "GrColor.h" 128072caa80384292858d31ae34b7e19768875866bjoshualitt#include "GrProcessor.h" 138072caa80384292858d31ae34b7e19768875866bjoshualitt#include "GrShaderVar.h" 148072caa80384292858d31ae34b7e19768875866bjoshualitt 158072caa80384292858d31ae34b7e19768875866bjoshualitt/* 168072caa80384292858d31ae34b7e19768875866bjoshualitt * The GrPrimitiveProcessor represents some kind of geometric primitive. This includes the shape 178072caa80384292858d31ae34b7e19768875866bjoshualitt * of the primitive and the inherent color of the primitive. The GrPrimitiveProcessor is 188072caa80384292858d31ae34b7e19768875866bjoshualitt * responsible for providing a color and coverage input into the Ganesh rendering pipeline. Through 198072caa80384292858d31ae34b7e19768875866bjoshualitt * optimization, Ganesh may decide a different color, no color, and / or no coverage are required 208072caa80384292858d31ae34b7e19768875866bjoshualitt * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this 2109d994ecb30de2e62a31af2c16307af31fe0e0b3Brian Salomon * functionality. 228072caa80384292858d31ae34b7e19768875866bjoshualitt * 238072caa80384292858d31ae34b7e19768875866bjoshualitt * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the 24cb30bb2cb727e276792812c6390547dba474c831Brian Salomon * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final 25cb30bb2cb727e276792812c6390547dba474c831Brian Salomon * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve 26cb30bb2cb727e276792812c6390547dba474c831Brian Salomon * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its 27a811b1200cc0b5e3819c89f62def23ec203d4b5aBrian Salomon * getProcessorAnalysisInputs implementation. These seed values are processed by the 285298dc8bf30f580f551d130346c007efaf4b2098Brian Salomon * subsequent 2992aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in 3092aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon * the applyPipelineOptimizations call, where the op can use the information to inform decisions 3192aee3d6857386f2b5b8e1148e680a7b58e9b1fcBrian Salomon * about GrPrimitiveProcessor creation. 328072caa80384292858d31ae34b7e19768875866bjoshualitt */ 338072caa80384292858d31ae34b7e19768875866bjoshualitt 34e659a581f63fdccb64dce2dc8a478cf56831feeaegdanielclass GrGLSLPrimitiveProcessor; 358072caa80384292858d31ae34b7e19768875866bjoshualitt 368072caa80384292858d31ae34b7e19768875866bjoshualitt/* 378072caa80384292858d31ae34b7e19768875866bjoshualitt * GrPrimitiveProcessor defines an interface which all subclasses must implement. All 388072caa80384292858d31ae34b7e19768875866bjoshualitt * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage 398072caa80384292858d31ae34b7e19768875866bjoshualitt * pipelines, and they must provide some notion of equality 408072caa80384292858d31ae34b7e19768875866bjoshualitt */ 41d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomonclass GrPrimitiveProcessor : public GrResourceIOProcessor, public GrProgramElement { 428072caa80384292858d31ae34b7e19768875866bjoshualittpublic: 438072caa80384292858d31ae34b7e19768875866bjoshualitt struct Attribute { 441d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton enum class InputRate : bool { 451d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton kPerVertex, 461d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton kPerInstance 471d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton }; 4804460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon GrShaderVar asShaderVar() const { 4904460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon return GrShaderVar(fName, GrVertexAttribTypeToSLType(fType), 5004460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon GrShaderVar::kIn_TypeModifier); 5104460ccee50e03b89420cdaa85882a9da083fa38Brian Salomon } 52b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon bool isInitialized() const { return SkToBool(fName); } 53b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon Attribute() = default; 54b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon Attribute(const char* name, GrVertexAttribType type, int offset, InputRate rate) 55b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon : fName(name), fType(type), fOffsetInRecord(offset), fInputRate(rate) {} 56b5ef1f9b13e36a427dd6350986d41db208b2df1bBrian Salomon const char* fName = nullptr; 571d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton GrVertexAttribType fType; 581d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton int fOffsetInRecord; 591d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton InputRate fInputRate; 608072caa80384292858d31ae34b7e19768875866bjoshualitt }; 618072caa80384292858d31ae34b7e19768875866bjoshualitt 62abff956455637b12eab374fd44b99e1338799113Ethan Nicholas GrPrimitiveProcessor(ClassID classID) 63abff956455637b12eab374fd44b99e1338799113Ethan Nicholas : GrResourceIOProcessor(classID) {} 64abff956455637b12eab374fd44b99e1338799113Ethan Nicholas 657dbd45d2c7427d2c679d6507435d2f0220bf64efbsalomon int numAttribs() const { return fAttribs.count(); } 667dbd45d2c7427d2c679d6507435d2f0220bf64efbsalomon const Attribute& getAttrib(int index) const { return fAttribs[index]; } 678072caa80384292858d31ae34b7e19768875866bjoshualitt 681d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton bool hasVertexAttribs() const { return SkToBool(fVertexStride); } 691d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton bool hasInstanceAttribs() const { return SkToBool(fInstanceStride); } 701d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton 711d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton /** 721d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * These return the strides of the vertex and instance buffers. Attributes are expected to be 731d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * laid out interleaved in their corresponding buffer (vertex or instance). fOffsetInRecord 741d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * indicates an attribute's location in bytes relative to the first attribute. (These are padded 751d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * to the nearest 4 bytes for performance reasons.) 761d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * 771d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * A common practice is to populate the buffer's memory using an implicit array of structs. In 781d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * this case, it is best to assert: 791d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * 801d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * stride == sizeof(struct) and 811d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * offsetof(struct, field[i]) == attrib[i].fOffsetInRecord 821d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * 831d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * NOTE: for instanced draws the vertex buffer has a single record that each instance reuses. 841d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton */ 851d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton int getVertexStride() const { return fVertexStride; } 861d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton int getInstanceStride() const { return fInstanceStride; } 871d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton 881d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but 891d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton // we put these calls on the base class to prevent having to cast 901d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton virtual bool willUseGeoShader() const = 0; 918072caa80384292858d31ae34b7e19768875866bjoshualitt 9227059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton bool willUsePrimitiveRestart() const { return fWillUsePrimitiveRestart; } 9327059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton 948072caa80384292858d31ae34b7e19768875866bjoshualitt /** 95a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix * Computes a transformKey from an array of coord transforms. Will only look at the first 96a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix * <numCoords> transforms in the array. 97a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix * 98a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix * TODO: A better name for this function would be "compute" instead of "get". 998072caa80384292858d31ae34b7e19768875866bjoshualitt */ 100a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords, 101a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix int numCoords) const; 1028072caa80384292858d31ae34b7e19768875866bjoshualitt 1038072caa80384292858d31ae34b7e19768875866bjoshualitt /** 1048072caa80384292858d31ae34b7e19768875866bjoshualitt * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry 1058072caa80384292858d31ae34b7e19768875866bjoshualitt * processor's GL backend implementation. 106a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix * 107a7f4c435bc1dcd845990a5515828bbe8cccfab41wangyix * TODO: A better name for this function would be "compute" instead of "get". 1088072caa80384292858d31ae34b7e19768875866bjoshualitt */ 10994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0; 1108072caa80384292858d31ae34b7e19768875866bjoshualitt 1118072caa80384292858d31ae34b7e19768875866bjoshualitt 1128072caa80384292858d31ae34b7e19768875866bjoshualitt /** Returns a new instance of the appropriate *GL* implementation class 1138072caa80384292858d31ae34b7e19768875866bjoshualitt for the given GrProcessor; caller is responsible for deleting 1148072caa80384292858d31ae34b7e19768875866bjoshualitt the object. */ 11594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0; 1168072caa80384292858d31ae34b7e19768875866bjoshualitt 1172279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas virtual bool isPathRendering() const { return false; } 1188072caa80384292858d31ae34b7e19768875866bjoshualitt 1192279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas /** 1202279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor(). 1212279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas */ 1222279325d539700ee3da29d6e874b3b3ce1dcf49cethannicholas virtual const char* getDestColorOverride() const { return nullptr; } 1239d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary 12428ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas virtual float getSampleShading() const { 12528ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas return 0.0; 12628ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas } 12728ef445d2e55ada7a45fd74e9248b4f22b16e061ethannicholas 1288072caa80384292858d31ae34b7e19768875866bjoshualittprotected: 1291d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton /** 1301d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton * Subclasses call these from their constructor to register vertex and instance attributes. 1311d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton */ 132fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas const Attribute& addVertexAttrib(const char* name, GrVertexAttribType type) { 133fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas fAttribs.push_back() = {name, type, fVertexStride, Attribute::InputRate::kPerVertex}; 1341d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton fVertexStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type))); 1351d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton return fAttribs.back(); 1361d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton } 137fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas const Attribute& addInstanceAttrib(const char* name, GrVertexAttribType type) { 138fa7ee2447e6227e7f441d32e570489130c0932bbEthan Nicholas fAttribs.push_back() = {name, type, fInstanceStride, Attribute::InputRate::kPerInstance}; 1391d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton fInstanceStride += static_cast<int>(SkAlign4(GrVertexAttribTypeSize(type))); 1401d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton return fAttribs.back(); 1411d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton } 1428072caa80384292858d31ae34b7e19768875866bjoshualitt 14327059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton void setWillUsePrimitiveRestart() { fWillUsePrimitiveRestart = true; } 14427059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton 1458072caa80384292858d31ae34b7e19768875866bjoshualittprivate: 146d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon void addPendingIOs() const override { GrResourceIOProcessor::addPendingIOs(); } 147d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon void removeRefs() const override { GrResourceIOProcessor::removeRefs(); } 148d61c9d93b126dca0af17eff89be8536944dadf81Brian Salomon void pendingIOComplete() const override { GrResourceIOProcessor::pendingIOComplete(); } 149fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein void notifyRefCntIsZero() const final {} 1508072caa80384292858d31ae34b7e19768875866bjoshualitt virtual bool hasExplicitLocalCoords() const = 0; 1518072caa80384292858d31ae34b7e19768875866bjoshualitt 15227059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton SkSTArray<8, Attribute> fAttribs; 15327059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton int fVertexStride = 0; 15427059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton int fInstanceStride = 0; 15527059d36d63284b1af2c25e0e5a52c17485c54d7Chris Dalton bool fWillUsePrimitiveRestart = false; 1561d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton 1578072caa80384292858d31ae34b7e19768875866bjoshualitt typedef GrProcessor INHERITED; 1588072caa80384292858d31ae34b7e19768875866bjoshualitt}; 1598072caa80384292858d31ae34b7e19768875866bjoshualitt 1608072caa80384292858d31ae34b7e19768875866bjoshualitt#endif 161