1/* 2 * Copyright 2013 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#ifndef GrGeometryProcessor_DEFINED 9#define GrGeometryProcessor_DEFINED 10 11#include "GrPrimitiveProcessor.h" 12 13/** 14 * A GrGeometryProcessor is a flexible method for rendering a primitive. The GrGeometryProcessor 15 * has complete control over vertex attributes and uniforms(aside from the render target) but it 16 * must obey the same contract as any GrPrimitiveProcessor, specifically it must emit a color and 17 * coverage into the fragment shader. Where this color and coverage come from is completely the 18 * responsibility of the GrGeometryProcessor. 19 */ 20class GrGeometryProcessor : public GrPrimitiveProcessor { 21public: 22 GrGeometryProcessor() 23 : INHERITED(false) 24 , fWillUseGeoShader(false) 25 , fHasLocalCoords(false) {} 26 27 bool willUseGeoShader() const { return fWillUseGeoShader; } 28 29 // TODO delete this when paths are in batch 30 bool canMakeEqual(const GrBatchTracker& mine, 31 const GrPrimitiveProcessor& that, 32 const GrBatchTracker& theirs) const override { 33 SkFAIL("Unsupported\n"); 34 return false; 35 } 36 37 // TODO Delete when paths are in batch 38 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 39 SkFAIL("Unsupported\n"); 40 } 41 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { 42 SkFAIL("Unsupported\n"); 43 } 44 45protected: 46 /* 47 * An optional simple helper function to determine by what means the GrGeometryProcessor should 48 * use to provide color. If we are given an override color(ie the given overridecolor is NOT 49 * GrColor_ILLEGAL) then we must always emit that color(currently overrides are only supported 50 * via uniform, but with deferred Geometry we could use attributes). Otherwise, if our color is 51 * ignored then we should not emit a color. Lastly, if we don't have vertex colors then we must 52 * emit a color via uniform 53 * TODO this function changes quite a bit with deferred geometry. There the GrGeometryProcessor 54 * can upload a new color via attribute if needed. 55 */ 56 static GrGPInput GetColorInputType(GrColor* color, GrColor primitiveColor, 57 const GrPipelineInfo& init, 58 bool hasVertexColor) { 59 if (init.fColorIgnored) { 60 *color = GrColor_ILLEGAL; 61 return kIgnored_GrGPInput; 62 } else if (GrColor_ILLEGAL != init.fOverrideColor) { 63 *color = init.fOverrideColor; 64 return kUniform_GrGPInput; 65 } 66 67 *color = primitiveColor; 68 if (hasVertexColor) { 69 return kAttribute_GrGPInput; 70 } else { 71 return kUniform_GrGPInput; 72 } 73 } 74 75 /** 76 * Subclasses call this from their constructor to register vertex attributes. Attributes 77 * will be padded to the nearest 4 bytes for performance reasons. 78 * TODO After deferred geometry, we should do all of this inline in GenerateGeometry alongside 79 * the struct used to actually populate the attributes. This is all extremely fragile, vertex 80 * attributes have to be added in the order they will appear in the struct which maps memory. 81 * The processor key should reflect the vertex attributes, or there lack thereof in the 82 * GrGeometryProcessor. 83 */ 84 const Attribute& addVertexAttrib(const Attribute& attribute) { 85 SkASSERT(fNumAttribs < kMaxVertexAttribs); 86 fVertexStride += attribute.fOffset; 87 fAttribs[fNumAttribs] = attribute; 88 return fAttribs[fNumAttribs++]; 89 } 90 91 void setWillUseGeoShader() { fWillUseGeoShader = true; } 92 93 // TODO hack see above 94 void setHasLocalCoords() { fHasLocalCoords = true; } 95 96private: 97 bool hasExplicitLocalCoords() const override { return fHasLocalCoords; } 98 99 bool fWillUseGeoShader; 100 bool fHasLocalCoords; 101 102 typedef GrPrimitiveProcessor INHERITED; 103}; 104 105#endif 106