GrProcessor.h revision ab84fae29fdee95987b10c00ff34957476a66263
1168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com/* 2168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com * Copyright 2012 Google Inc. 3168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com * 4168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be 5168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com * found in the LICENSE file. 6168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com */ 7168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com 8b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#ifndef GrProcessor_DEFINED 9b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#define GrProcessor_DEFINED 10168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com 11b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrBackendProcessorFactory.h" 12371e105da5d9fdfff3b4242b37ff6fc09214c8c8bsalomon@google.com#include "GrColor.h" 13b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#include "GrProcessorUnitTest.h" 1495740981c36266e4595ddde2264aa38e3c7e2d02bsalomon#include "GrProgramElement.h" 15249af15fb82833d2274850c589812b6e69df0033joshualitt#include "GrShaderVar.h" 16047696c1c67b2e0a73f2b951ce23ff5b155111bbbsalomon@google.com#include "GrTextureAccess.h" 17ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org#include "GrTypesPriv.h" 18249af15fb82833d2274850c589812b6e69df0033joshualitt#include "SkString.h" 1907eecdca3e331eb4066c53a29305aeea6d692961tomhudson@google.com 20b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrBackendProcessorFactory; 21168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.comclass GrContext; 2277af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.comclass GrCoordTransform; 2395740981c36266e4595ddde2264aa38e3c7e2d02bsalomon 2450db75c871b203081a32190ab173f13c785a147fbsalomon@google.com/** Provides custom vertex shader, fragment shader, uniform data for a particular stage of the 2550db75c871b203081a32190ab173f13c785a147fbsalomon@google.com Ganesh shading pipeline. 26289efe014ad7628de7cf2c5177a42cacd1e335adbsalomon@google.com Subclasses must have a function that produces a human-readable name: 27289efe014ad7628de7cf2c5177a42cacd1e335adbsalomon@google.com static const char* Name(); 28b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessor objects *must* be immutable: after being constructed, their fields may not change. 290ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 30b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt Dynamically allocated GrProcessors are managed by a per-thread memory pool. The ref count of an 3197b9ab72cd5ee0cba4692082737266376425f27cbsalomon effect must reach 0 before the thread terminates and the pool is destroyed. To create a static 3297b9ab72cd5ee0cba4692082737266376425f27cbsalomon effect use the macro GR_CREATE_STATIC_EFFECT declared below. 33289efe014ad7628de7cf2c5177a42cacd1e335adbsalomon@google.com */ 34b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrProcessor : public GrProgramElement { 35168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.compublic: 36b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SK_DECLARE_INST_COUNT(GrProcessor) 3715e9d3e66e161ce23df30bc13f8a0c87d196b463robertphillips@google.com 38b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual ~GrProcessor(); 39168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com 401a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel struct InvariantOutput{ 41ab84fae29fdee95987b10c00ff34957476a66263egdaniel InvariantOutput() : fColor(0), fValidFlags(0), fIsSingleComponent(false), 42ab84fae29fdee95987b10c00ff34957476a66263egdaniel fNonMulStageFound(false) {} 43651713408c5a5d9565665967ad09981250c7a8c9joshualitt 44ccb2e384a036f29d989d3c1468f879324e81a678egdaniel void mulByUnknownOpaqueColor() { 45ccb2e384a036f29d989d3c1468f879324e81a678egdaniel if (this->isOpaque()) { 46ccb2e384a036f29d989d3c1468f879324e81a678egdaniel fValidFlags = kA_GrColorComponentFlag; 47ccb2e384a036f29d989d3c1468f879324e81a678egdaniel fIsSingleComponent = false; 48ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } else { 49ccb2e384a036f29d989d3c1468f879324e81a678egdaniel // Since the current state is not opaque we no longer care if the color being 50ccb2e384a036f29d989d3c1468f879324e81a678egdaniel // multiplied is opaque. 51ccb2e384a036f29d989d3c1468f879324e81a678egdaniel this->mulByUnknownColor(); 52ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 53ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 54ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 55ccb2e384a036f29d989d3c1468f879324e81a678egdaniel void mulByUnknownColor() { 56ccb2e384a036f29d989d3c1468f879324e81a678egdaniel if (this->hasZeroAlpha()) { 57ab84fae29fdee95987b10c00ff34957476a66263egdaniel this->internalSetToTransparentBlack(); 58ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } else { 59ab84fae29fdee95987b10c00ff34957476a66263egdaniel this->internalSetToUnknown(); 60ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 61ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 62ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 63ccb2e384a036f29d989d3c1468f879324e81a678egdaniel void mulByUnknownAlpha() { 64ccb2e384a036f29d989d3c1468f879324e81a678egdaniel if (this->hasZeroAlpha()) { 65ab84fae29fdee95987b10c00ff34957476a66263egdaniel this->internalSetToTransparentBlack(); 66ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } else { 67ccb2e384a036f29d989d3c1468f879324e81a678egdaniel // We don't need to change fIsSingleComponent in this case 68ccb2e384a036f29d989d3c1468f879324e81a678egdaniel fValidFlags = 0; 69ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 70ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 71ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 72ccb2e384a036f29d989d3c1468f879324e81a678egdaniel void invalidateComponents(uint8_t invalidateFlags) { 73ccb2e384a036f29d989d3c1468f879324e81a678egdaniel fValidFlags &= ~invalidateFlags; 74ccb2e384a036f29d989d3c1468f879324e81a678egdaniel fIsSingleComponent = false; 75ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 76ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 77ccb2e384a036f29d989d3c1468f879324e81a678egdaniel void setToTransparentBlack() { 78ab84fae29fdee95987b10c00ff34957476a66263egdaniel this->internalSetToTransparentBlack(); 79ab84fae29fdee95987b10c00ff34957476a66263egdaniel fNonMulStageFound = true; 80ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 81ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 82ccb2e384a036f29d989d3c1468f879324e81a678egdaniel void setToOther(uint8_t validFlags, GrColor color) { 83ccb2e384a036f29d989d3c1468f879324e81a678egdaniel fValidFlags = validFlags; 84ccb2e384a036f29d989d3c1468f879324e81a678egdaniel fColor = color; 85ccb2e384a036f29d989d3c1468f879324e81a678egdaniel fIsSingleComponent = false; 86ab84fae29fdee95987b10c00ff34957476a66263egdaniel fNonMulStageFound = true; 87ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 88ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 89ccb2e384a036f29d989d3c1468f879324e81a678egdaniel void setToUnknown() { 90ab84fae29fdee95987b10c00ff34957476a66263egdaniel this->internalSetToUnknown(); 91ab84fae29fdee95987b10c00ff34957476a66263egdaniel fNonMulStageFound= true; 92ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 93ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 941a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel bool isOpaque() const { 951a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel return ((fValidFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(fColor)); 961a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel } 971a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 981a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel bool isSolidWhite() const { 991a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel return (fValidFlags == kRGBA_GrColorComponentFlags && 0xFFFFFFFF == fColor); 1001a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel } 1011a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 102ccb2e384a036f29d989d3c1468f879324e81a678egdaniel GrColor color() const { return fColor; } 103ccb2e384a036f29d989d3c1468f879324e81a678egdaniel uint8_t validFlags() const { return fValidFlags; } 104ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 1051a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel /** 1061a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * If isSingleComponent is true, then the flag values for r, g, b, and a must all be the 1071a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * same. If the flags are all set then all color components must be equal. 1081a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel */ 1091a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel SkDEBUGCODE(void validate() const;) 1101a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 1111a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel private: 112ab84fae29fdee95987b10c00ff34957476a66263egdaniel void internalSetToTransparentBlack() { 113ab84fae29fdee95987b10c00ff34957476a66263egdaniel fValidFlags = kRGBA_GrColorComponentFlags; 114ab84fae29fdee95987b10c00ff34957476a66263egdaniel fColor = 0; 115ab84fae29fdee95987b10c00ff34957476a66263egdaniel fIsSingleComponent = true; 116ab84fae29fdee95987b10c00ff34957476a66263egdaniel } 117ab84fae29fdee95987b10c00ff34957476a66263egdaniel 118ab84fae29fdee95987b10c00ff34957476a66263egdaniel void internalSetToUnknown() { 119ab84fae29fdee95987b10c00ff34957476a66263egdaniel fValidFlags = 0; 120ab84fae29fdee95987b10c00ff34957476a66263egdaniel fIsSingleComponent = false; 121ab84fae29fdee95987b10c00ff34957476a66263egdaniel } 122ab84fae29fdee95987b10c00ff34957476a66263egdaniel 123ccb2e384a036f29d989d3c1468f879324e81a678egdaniel bool hasZeroAlpha() const { 124ccb2e384a036f29d989d3c1468f879324e81a678egdaniel return ((fValidFlags & kA_GrColorComponentFlag) && 0 == GrColorUnpackA(fColor)); 125ccb2e384a036f29d989d3c1468f879324e81a678egdaniel } 1261a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 127ccb2e384a036f29d989d3c1468f879324e81a678egdaniel SkDEBUGCODE(bool colorComponentsAllEqual() const;) 1281a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel /** 1291a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * If alpha is valid, check that any valid R,G,B values are <= A 1301a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel */ 1311a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel SkDEBUGCODE(bool validPreMulColor() const;) 132ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 133ccb2e384a036f29d989d3c1468f879324e81a678egdaniel // Friended class that have "controller" code which loop over stages calling 134ccb2e384a036f29d989d3c1468f879324e81a678egdaniel // computeInvarianteOutput(). These controllers may need to manually adjust the internal 135ccb2e384a036f29d989d3c1468f879324e81a678egdaniel // members of InvariantOutput 136ccb2e384a036f29d989d3c1468f879324e81a678egdaniel friend class GrDrawState; 137ccb2e384a036f29d989d3c1468f879324e81a678egdaniel friend class GrOptDrawState; 138ccb2e384a036f29d989d3c1468f879324e81a678egdaniel friend class GrPaint; 139ccb2e384a036f29d989d3c1468f879324e81a678egdaniel 140ccb2e384a036f29d989d3c1468f879324e81a678egdaniel GrColor fColor; 141ccb2e384a036f29d989d3c1468f879324e81a678egdaniel uint32_t fValidFlags; 142ccb2e384a036f29d989d3c1468f879324e81a678egdaniel bool fIsSingleComponent; 143ab84fae29fdee95987b10c00ff34957476a66263egdaniel bool fNonMulStageFound; 1441a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel }; 1451a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel 146371e105da5d9fdfff3b4242b37ff6fc09214c8c8bsalomon@google.com /** 1471a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * This function is used to perform optimizations. When called the invarientOuput param 148b8eb2e89edf914caf5479baeffcb670d3e93f496bsalomon@google.com * indicate whether the input components to this effect in the FS will have known values. 1491a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent 1501a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * member indicates whether the input will be 1 or 4 bytes. The function updates the members of 1511a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * inout to indicate known values of its output. A component of the color member only has 1521a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * meaning if the corresponding bit in validFlags is set. 153371e105da5d9fdfff3b4242b37ff6fc09214c8c8bsalomon@google.com */ 1541a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel void computeInvariantOutput(InvariantOutput* inout) const { 1551a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel this->onComputeInvariantOutput(inout); 1561a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel#ifdef SK_DEBUG 1571a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel inout->validate(); 1581a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel#endif 1591a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel } 160168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com 161422e81aeb1f4078367c85efe591c7df8c33874ecbsalomon@google.com /** This object, besides creating back-end-specific helper objects, is used for run-time-type- 162422e81aeb1f4078367c85efe591c7df8c33874ecbsalomon@google.com identification. The factory should be an instance of templated class, 163b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrTBackendEffectFactory. It is templated on the subclass of GrProcessor. The subclass must 164b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt have a nested type (or typedef) named GLProcessor which will be the subclass of 165b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrGLProcessor created by the factory. 166ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com 167ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com Example: 168b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt class MyCustomEffect : public GrProcessor { 169ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com ... 170396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 171396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com return GrTBackendEffectFactory<MyCustomEffect>::getInstance(); 172ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com } 173ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com ... 174ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com }; 175ae4f96a9e06df44f70c3d5f7324f5a7fabcd1026bsalomon@google.com */ 176b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendProcessorFactory& getFactory() const = 0; 177b88bbd2a5388ec2a5574d0ef7e43160c0ac37a3btomhudson@google.com 17868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com /** Returns true if this and other effect conservatively draw identically. It can only return 17968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com true when the two effects are of the same subclass (i.e. they return the same object from 18068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com from getFactory()). 18168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 18268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com A return value of true from isEqual() should not be used to test whether the effects would 18363e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon generate the same shader code. To test for identical code generation use the effects' keys 18463e99f7a03b2ac90ae7a00232674fd39c0bdcc68bsalomon computed by the GrBackendEffectFactory. 185d0c1a06cb98dd4a009dfa79e37ba6ca23a8c180btomhudson@google.com */ 186b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool isEqual(const GrProcessor& other) const { 18797b9ab72cd5ee0cba4692082737266376425f27cbsalomon if (&this->getFactory() != &other.getFactory()) { 18897b9ab72cd5ee0cba4692082737266376425f27cbsalomon return false; 18997b9ab72cd5ee0cba4692082737266376425f27cbsalomon } 19097b9ab72cd5ee0cba4692082737266376425f27cbsalomon bool result = this->onIsEqual(other); 19197b9ab72cd5ee0cba4692082737266376425f27cbsalomon#ifdef SK_DEBUG 19297b9ab72cd5ee0cba4692082737266376425f27cbsalomon if (result) { 19397b9ab72cd5ee0cba4692082737266376425f27cbsalomon this->assertEquality(other); 19497b9ab72cd5ee0cba4692082737266376425f27cbsalomon } 19597b9ab72cd5ee0cba4692082737266376425f27cbsalomon#endif 19697b9ab72cd5ee0cba4692082737266376425f27cbsalomon return result; 19768b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com } 198d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com 199a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com /** Human-meaningful string to identify this effect; may be embedded 200a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com in generated shader code. */ 2012eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com const char* name() const; 202289efe014ad7628de7cf2c5177a42cacd1e335adbsalomon@google.com 20350db75c871b203081a32190ab173f13c785a147fbsalomon@google.com int numTextures() const { return fTextureAccesses.count(); } 204168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com 2056d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com /** Returns the access pattern for the texture at index. index must be valid according to 2066d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com numTextures(). */ 20750db75c871b203081a32190ab173f13c785a147fbsalomon@google.com const GrTextureAccess& textureAccess(int index) const { return *fTextureAccesses[index]; } 2086d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com 2096d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com /** Shortcut for textureAccess(index).texture(); */ 2106d003d1ddced3e71684b8b3785d1e5a16255688dbsalomon@google.com GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); } 211a5e65ec434fed44dc616e4f64950b835b541181btwiz@google.com 2128d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org /** Will this effect read the fragment position? */ 2138d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org bool willReadFragmentPosition() const { return fWillReadFragmentPosition; } 214ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org 215dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com void* operator new(size_t size); 216dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com void operator delete(void* target); 217dcba4c2cc30cc64f08def991376c6dab65cfb51ctomhudson@google.com 218d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com void* operator new(size_t size, void* placement) { 219d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com return ::operator new(size, placement); 220d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com } 221d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com void operator delete(void* target, void* placement) { 222d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com ::operator delete(target, placement); 223d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com } 224d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com 22549586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt /** 226b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * Helper for down-casting to a GrProcessor subclass 22749586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt */ 22849586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt template <typename T> const T& cast() const { return *static_cast<const T*>(this); } 22949586bec7383d4ccb81f85f8e2dc4162e2d4f6a8joshualitt 23050db75c871b203081a32190ab173f13c785a147fbsalomon@google.comprotected: 23150db75c871b203081a32190ab173f13c785a147fbsalomon@google.com /** 23291274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com * Subclasses call this from their constructor to register GrTextureAccesses. The effect 23391a798f121a2238639f8e2d08cc776d4f0236cebcommit-bot@chromium.org * subclass manages the lifetime of the accesses (this function only stores a pointer). The 234b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * GrTextureAccess is typically a member field of the GrProcessor subclass. This must only be 235b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * called from the constructor because GrProcessors are immutable. 23650db75c871b203081a32190ab173f13c785a147fbsalomon@google.com */ 23750db75c871b203081a32190ab173f13c785a147fbsalomon@google.com void addTextureAccess(const GrTextureAccess* textureAccess); 23850db75c871b203081a32190ab173f13c785a147fbsalomon@google.com 239b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrProcessor() 240b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt : fWillReadFragmentPosition(false) {} 2418d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org 2428d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org /** 2438d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org * If the effect will generate a backend-specific effect that will read the fragment position 2448d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org * in the FS then it must call this method from its constructor. Otherwise, the request to 2458d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org * access the fragment position will be denied. 2468d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org */ 2478d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; } 24826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 249d0c1a06cb98dd4a009dfa79e37ba6ca23a8c180btomhudson@google.comprivate: 250b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt SkDEBUGCODE(void assertEquality(const GrProcessor& other) const;) 25177af6805e5faea1e2a5c0220098aec9082f3a6e5bsalomon@google.com 25268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com /** Subclass implements this to support isEqual(). It will only be called if it is known that 2536340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com the two effects are of the same subclass (i.e. they return the same object from 2546340a41108633ac1ce5941e5cd30538630c4c55bbsalomon@google.com getFactory()).*/ 255b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual bool onIsEqual(const GrProcessor& other) const = 0; 25668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com 2571a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel /** 2581a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel * Subclass implements this to support getConstantColorComponents(...). 2591a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel */ 2601a8ecdfb73a15de600d5779b75d7c4b61863c50begdaniel virtual void onComputeInvariantOutput(InvariantOutput* inout) const = 0; 2610ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 262ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses; 2638d47ddc19a40d1984bf1f384d711d36ab59fd1c0commit-bot@chromium.org bool fWillReadFragmentPosition; 2640ac6af49975c54c2debf41e9200af416ecd2d973bsalomon@google.com 26595740981c36266e4595ddde2264aa38e3c7e2d02bsalomon typedef GrProgramElement INHERITED; 266168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com}; 267168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com 268b0a8a377f832c59cee939ad721e1f87d378b7142joshualittclass GrFragmentProcessor : public GrProcessor { 269b0a8a377f832c59cee939ad721e1f87d378b7142joshualittpublic: 270b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt GrFragmentProcessor() 271b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt : INHERITED() 272b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt , fWillReadDstColor(false) 273b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt , fWillUseInputColor(true) {} 274b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 275b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt virtual const GrBackendFragmentProcessorFactory& getFactory() const = 0; 276b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 277a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt int numTransforms() const { return fCoordTransforms.count(); } 278a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt 279a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt /** Returns the coordinate transformation at index. index must be valid according to 280a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt numTransforms(). */ 281a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; } 282a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt 283b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt /** Will this effect read the destination pixel value? */ 284b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool willReadDstColor() const { return fWillReadDstColor; } 285b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 286b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt /** Will this effect read the source color value? */ 287b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool willUseInputColor() const { return fWillUseInputColor; } 288b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 289b0a8a377f832c59cee939ad721e1f87d378b7142joshualittprotected: 290b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt /** 291a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt * Fragment Processor subclasses call this from their constructor to register coordinate 292a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt * transformations. The processor subclass manages the lifetime of the transformations (this 293a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt * function only stores a pointer). The GrCoordTransform is typically a member field of the 294a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt * GrProcessor subclass. When the matrix has perspective, the transformed coordinates will have 295a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt * 3 components. Otherwise they'll have 2. This must only be called from the constructor because 296a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt * GrProcessors are immutable. 297a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt */ 298a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt void addCoordTransform(const GrCoordTransform*); 299a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt 300a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt /** 301b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * If the effect subclass will read the destination pixel value then it must call this function 302b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * from its constructor. Otherwise, when its generated backend-specific effect class attempts 303b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * to generate code that reads the destination pixel it will fail. 304b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt */ 305b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt void setWillReadDstColor() { fWillReadDstColor = true; } 306b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 307b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt /** 308b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * If the effect will generate a result that does not depend on the input color value then it 309b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * must call this function from its constructor. Otherwise, when its generated backend-specific 310b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * code might fail during variable binding due to unused variables. 311b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt */ 312b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt void setWillNotUseInputColor() { fWillUseInputColor = false; } 313b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 314b0a8a377f832c59cee939ad721e1f87d378b7142joshualittprivate: 315a5305a110ab5201d5dadd40cbe711582d5ac4996joshualitt SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms; 316b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool fWillReadDstColor; 317b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt bool fWillUseInputColor; 318b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 319b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt typedef GrProcessor INHERITED; 320b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt}; 321b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt 322d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com/** 323d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com * This creates an effect outside of the effect memory pool. The effect's destructor will be called 324b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt * at global destruction time. NAME will be the name of the created GrProcessor. 325d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com */ 326b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt#define GR_CREATE_STATIC_FRAGMENT_PROCESSOR(NAME, EFFECT_CLASS, ARGS) \ 32797b9ab72cd5ee0cba4692082737266376425f27cbsalomonstatic SkAlignedSStorage<sizeof(EFFECT_CLASS)> g_##NAME##_Storage; \ 328b0a8a377f832c59cee939ad721e1f87d378b7142joshualittstatic GrFragmentProcessor* \ 329b0a8a377f832c59cee939ad721e1f87d378b7142joshualittNAME SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), EFFECT_CLASS, ARGS); \ 330b0a8a377f832c59cee939ad721e1f87d378b7142joshualittstatic SkAutoTDestroy<GrFragmentProcessor> NAME##_ad(NAME); 331d42aca31b9ddc1cb9a81522b4c73a9fe550450bcbsalomon@google.com 332168e63418cadba4018aadf95c091d40d9deb13b9tomhudson@google.com#endif 333