16251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon/* 26251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * Copyright 2014 Google Inc. 36251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * 46251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * Use of this source code is governed by a BSD-style license that can be 56251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * found in the LICENSE file. 66251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon */ 76251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 86251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon#ifndef GrFragmentProcessor_DEFINED 96251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon#define GrFragmentProcessor_DEFINED 106251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 116251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon#include "GrProcessor.h" 126251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 136251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonclass GrCoordTransform; 14e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverthclass GrGLSLCaps; 1564c4728c70001ed074fecf5c4e083781987b12e9egdanielclass GrGLSLFragmentProcessor; 16c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomonclass GrInvariantOutput; 17eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittclass GrProcessorKeyBuilder; 186251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 196251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon/** Provides custom fragment shader code. Fragment processors receive an input color (vec4f) and 206251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon produce an output color. They may reference textures and uniforms. They may use 216251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon GrCoordTransforms to receive a transformation of the local coordinates that map from local space 226251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon to the fragment being processed. 236251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon */ 246251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonclass GrFragmentProcessor : public GrProcessor { 256251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonpublic: 2687ba62e67c9ed0c453754a5341255829075c8e22bsalomon /** 2787ba62e67c9ed0c453754a5341255829075c8e22bsalomon * In many instances (e.g. SkShader::asFragmentProcessor() implementations) it is desirable to 2887ba62e67c9ed0c453754a5341255829075c8e22bsalomon * only consider the input color's alpha. However, there is a competing desire to have reusable 2987ba62e67c9ed0c453754a5341255829075c8e22bsalomon * GrFragmentProcessor subclasses that can be used in other scenarios where the entire input 3087ba62e67c9ed0c453754a5341255829075c8e22bsalomon * color is considered. This function exists to filter the input color and pass it to a FP. It 3187ba62e67c9ed0c453754a5341255829075c8e22bsalomon * does so by returning a parent FP that multiplies the passed in FPs output by the parent's 3287ba62e67c9ed0c453754a5341255829075c8e22bsalomon * input alpha. The passed in FP will not receive an input color. 3387ba62e67c9ed0c453754a5341255829075c8e22bsalomon */ 34f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon static const GrFragmentProcessor* MulOutputByInputAlpha(const GrFragmentProcessor*); 35f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 36f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon /** 37f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon * Similar to the above but it modulates the output r,g,b of the child processor by the input 38f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon * rgb and then multiplies all the components by the input alpha. This effectively modulates 39f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon * the child processor's premul color by a unpremul'ed input and produces a premul output 40f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon */ 41f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon static const GrFragmentProcessor* MulOutputByInputUnpremulColor(const GrFragmentProcessor*); 42f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon 43f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon /** 44e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon * Returns a parent fragment processor that adopts the passed fragment processor as a child. 45e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon * The parent will ignore its input color and instead feed the passed in color as input to the 46e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon * child. 47f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon */ 48f1b7a1d82860e106ed7d3e0e876419e65783fb84bsalomon static const GrFragmentProcessor* OverrideInput(const GrFragmentProcessor*, GrColor); 4987ba62e67c9ed0c453754a5341255829075c8e22bsalomon 50e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon /** 51e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon * Returns a fragment processor that runs the passed in array of fragment processors in a 52e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon * series. The original input is passed to the first, the first's output is passed to the 53e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon * second, etc. The output of the returned processor is the output of the last processor of the 54e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon * series. 55e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon */ 56e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon static const GrFragmentProcessor* RunInSeries(const GrFragmentProcessor*[], int cnt); 57e25eea4b36a488448fb730f4e3dc5a900b0e2892bsalomon 586251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon GrFragmentProcessor() 596251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon : INHERITED() 6093ab254b7e4ce82074e88e219a8e32b31086ca86wangyix , fUsesLocalCoords(false) 6193ab254b7e4ce82074e88e219a8e32b31086ca86wangyix , fNumTexturesExclChildren(0) 6293ab254b7e4ce82074e88e219a8e32b31086ca86wangyix , fNumTransformsExclChildren(0) {} 636251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 64ac856c97acc84dcb54d9cdb068ec8a02b8869647bsalomon ~GrFragmentProcessor() override; 65ac856c97acc84dcb54d9cdb068ec8a02b8869647bsalomon 6657d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrGLSLFragmentProcessor* createGLSLInstance() const; 67eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 6857d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel void getGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const { 6957d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel this->onGetGLSLProcessorKey(caps, b); 704b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix for (int i = 0; i < fChildProcessors.count(); ++i) { 7157d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel fChildProcessors[i]->getGLSLProcessorKey(caps, b); 724b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix } 734b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix } 744b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix 7593ab254b7e4ce82074e88e219a8e32b31086ca86wangyix int numTexturesExclChildren() const { return fNumTexturesExclChildren; } 7693ab254b7e4ce82074e88e219a8e32b31086ca86wangyix 7793ab254b7e4ce82074e88e219a8e32b31086ca86wangyix int numTransformsExclChildren() const { return fNumTransformsExclChildren; } 7893ab254b7e4ce82074e88e219a8e32b31086ca86wangyix 796251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon int numTransforms() const { return fCoordTransforms.count(); } 806251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 816251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon /** Returns the coordinate transformation at index. index must be valid according to 826251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon numTransforms(). */ 836251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; } 846251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 85abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt const SkTArray<const GrCoordTransform*, true>& coordTransforms() const { 86abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt return fCoordTransforms; 87abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt } 88abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 892fe7923f7e74f901a17afba7609d71a1220bdc60joshualitt void gatherCoordTransforms(SkTArray<const GrCoordTransform*, true>* outTransforms) const { 9058d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix if (!fCoordTransforms.empty()) { 9158d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix outTransforms->push_back_n(fCoordTransforms.count(), fCoordTransforms.begin()); 922fe7923f7e74f901a17afba7609d71a1220bdc60joshualitt } 932fe7923f7e74f901a17afba7609d71a1220bdc60joshualitt } 942fe7923f7e74f901a17afba7609d71a1220bdc60joshualitt 954b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix int numChildProcessors() const { return fChildProcessors.count(); } 964b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix 97ac856c97acc84dcb54d9cdb068ec8a02b8869647bsalomon const GrFragmentProcessor& childProcessor(int index) const { return *fChildProcessors[index]; } 984b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix 99290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt /** Do any of the coordtransforms for this processor require local coords? */ 100290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool usesLocalCoords() const { return fUsesLocalCoords; } 101290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt 102eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt /** Returns true if this and other processor conservatively draw identically. It can only return 103eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt true when the two processor are of the same subclass (i.e. they return the same object from 1046251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon from getFactory()). 1056251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 106eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt A return value of true from isEqual() should not be used to test whether the processor would 10757d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel generate the same shader code. To test for identical code generation use getGLSLProcessorKey 10857d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel */ 10954017d7e5b09e7ca58346ea72ff065677fcd7be1wangyix bool isEqual(const GrFragmentProcessor& that, bool ignoreCoordTransforms) const; 1106251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 11156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt /** 11256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * This function is used to perform optimizations. When called the invarientOuput param 11356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * indicate whether the input components to this processor in the FS will have known values. 11456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent 11556995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * member indicates whether the input will be 1 or 4 bytes. The function updates the members of 11656995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * inout to indicate known values of its output. A component of the color member only has 11756995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * meaning if the corresponding bit in validFlags is set. 11856995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt */ 119c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon void computeInvariantOutput(GrInvariantOutput* inout) const { 120c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon this->onComputeInvariantOutput(inout); 121c21b09eec91c9e263cb0b88467ea44e348ed4962bsalomon } 12256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt 1236251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonprotected: 12493ab254b7e4ce82074e88e219a8e32b31086ca86wangyix void addTextureAccess(const GrTextureAccess* textureAccess) override; 12593ab254b7e4ce82074e88e219a8e32b31086ca86wangyix 1266251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon /** 1276251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * Fragment Processor subclasses call this from their constructor to register coordinate 128de258cd6b402c4da78b66e88191ad02162d87916bsalomon * transformations. Coord transforms provide a mechanism for a processor to receive coordinates 129de258cd6b402c4da78b66e88191ad02162d87916bsalomon * in their FS code. The matrix expresses a transformation from local space. For a given 130de258cd6b402c4da78b66e88191ad02162d87916bsalomon * fragment the matrix will be applied to the local coordinate that maps to the fragment. 131de258cd6b402c4da78b66e88191ad02162d87916bsalomon * 132de258cd6b402c4da78b66e88191ad02162d87916bsalomon * When the transformation has perspective, the transformed coordinates will have 133790d74f7c1db73e2938eee6a6eb78bc29be7b851mtklein * 3 components. Otherwise they'll have 2. 134de258cd6b402c4da78b66e88191ad02162d87916bsalomon * 135de258cd6b402c4da78b66e88191ad02162d87916bsalomon * This must only be called from the constructor because GrProcessors are immutable. The 136de258cd6b402c4da78b66e88191ad02162d87916bsalomon * processor subclass manages the lifetime of the transformations (this function only stores a 137790d74f7c1db73e2938eee6a6eb78bc29be7b851mtklein * pointer). The GrCoordTransform is typically a member field of the GrProcessor subclass. 138de258cd6b402c4da78b66e88191ad02162d87916bsalomon * 139de258cd6b402c4da78b66e88191ad02162d87916bsalomon * A processor subclass that has multiple methods of construction should always add its coord 140de258cd6b402c4da78b66e88191ad02162d87916bsalomon * transforms in a consistent order. The non-virtual implementation of isEqual() automatically 141de258cd6b402c4da78b66e88191ad02162d87916bsalomon * compares transforms and will assume they line up across the two processor instances. 1426251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon */ 1436251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon void addCoordTransform(const GrCoordTransform*); 1446251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 1456251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon /** 14658d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix * FragmentProcessor subclasses call this from their constructor to register any child 14793ab254b7e4ce82074e88e219a8e32b31086ca86wangyix * FragmentProcessors they have. This must be called AFTER all texture accesses and coord 14893ab254b7e4ce82074e88e219a8e32b31086ca86wangyix * transforms have been added. 1494b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix * This is for processors whose shader code will be composed of nested processors whose output 1504b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix * colors will be combined somehow to produce its output color. Registering these child 15158d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix * processors will allow the ProgramBuilder to automatically handle their transformed coords and 15258d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix * texture accesses and mangle their uniform and output color names. 1534b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix */ 15458d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix int registerChildProcessor(const GrFragmentProcessor* child); 1554b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix 1564b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix /** 15756995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * Subclass implements this to support getConstantColorComponents(...). 15854017d7e5b09e7ca58346ea72ff065677fcd7be1wangyix * 15954017d7e5b09e7ca58346ea72ff065677fcd7be1wangyix * Note: it's up to the subclass implementation to do any recursive call to compute the child 16054017d7e5b09e7ca58346ea72ff065677fcd7be1wangyix * procs' output invariants; computeInvariantOutput will not be recursive. 16156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt */ 16256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0; 16356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt 1646251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonprivate: 1654204800cd8f311f11491cf2eb7e32ca681f05489bsalomon void notifyRefCntIsZero() const final; 1664204800cd8f311f11491cf2eb7e32ca681f05489bsalomon 167b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix /** Returns a new instance of the appropriate *GL* implementation class 168b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix for the given GrFragmentProcessor; caller is responsible for deleting 169b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix the object. */ 17057d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel virtual GrGLSLFragmentProcessor* onCreateGLSLInstance() const = 0; 171b1daa86732fe70aa4630c89d75ff0fd619d77c77wangyix 1724b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix /** Implemented using GLFragmentProcessor::GenKey as described in this class's comment. */ 17357d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, 17457d3b039c635945e1dc2fcbac3462ed8bfedb068egdaniel GrProcessorKeyBuilder* b) const = 0; 1754b3050b410254d0cb38df9a30ae2e209124fa1a2wangyix 176de258cd6b402c4da78b66e88191ad02162d87916bsalomon /** 177de258cd6b402c4da78b66e88191ad02162d87916bsalomon * Subclass implements this to support isEqual(). It will only be called if it is known that 178de258cd6b402c4da78b66e88191ad02162d87916bsalomon * the two processors are of the same subclass (i.e. they return the same object from 179de258cd6b402c4da78b66e88191ad02162d87916bsalomon * getFactory()). The processor subclass should not compare its coord transforms as that will 180de258cd6b402c4da78b66e88191ad02162d87916bsalomon * be performed automatically in the non-virtual isEqual(). 181de258cd6b402c4da78b66e88191ad02162d87916bsalomon */ 182de258cd6b402c4da78b66e88191ad02162d87916bsalomon virtual bool onIsEqual(const GrFragmentProcessor&) const = 0; 183de258cd6b402c4da78b66e88191ad02162d87916bsalomon 184de258cd6b402c4da78b66e88191ad02162d87916bsalomon bool hasSameTransforms(const GrFragmentProcessor&) const; 1856251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 186418e26f86c7a9dd2096cfc5501f86c559c7689d7bsalomon bool fUsesLocalCoords; 18758d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix 18858d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix /** 18969ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * fCoordTransforms stores the transforms of this proc, followed by all the transforms of this 19069ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * proc's children. In other words, each proc stores all the transforms of its subtree as if 19169ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * they were collected using preorder traversal. 19269ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * 19369ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * Example: 19469ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * Suppose we have frag proc A, who has two children B and D. B has a child C, and D has 19569ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * two children E and F. Suppose procs A, B, C, D, E, F have 1, 2, 1, 1, 3, 2 transforms 19669ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * respectively. The following shows what the fCoordTransforms array of each proc would contain: 19769ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * 19869ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * (A) 19969ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * [a1,b1,b2,c1,d1,e1,e2,e3,f1,f2] 20069ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * / \ 20169ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * / \ 20269ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * (B) (D) 20369ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * [b1,b2,c1] [d1,e1,e2,e3,f1,f2] 20469ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * / / \ 20569ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * / / \ 20669ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * (C) (E) (F) 20769ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * [c1] [e1,e2,e3] [f1,f2] 20869ed114d388c56e83a2385d8b8182e6d05a0b073wangyix * 20958d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix * The same goes for fTextureAccesses with textures. 21058d890bd45a201477ec6c4ba0ae61c574b4e5aefwangyix */ 211418e26f86c7a9dd2096cfc5501f86c559c7689d7bsalomon SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms; 212418e26f86c7a9dd2096cfc5501f86c559c7689d7bsalomon int fNumTexturesExclChildren; 213418e26f86c7a9dd2096cfc5501f86c559c7689d7bsalomon int fNumTransformsExclChildren; 214e416d940c64d7e9b3ef8eb62a2a4ce8e5794e13eBrian Salomon SkSTArray<1, const GrFragmentProcessor*, true> fChildProcessors; 2156251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 2166251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon typedef GrProcessor INHERITED; 2176251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon}; 2186251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 2196251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon#endif 220