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; 15eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittclass GrGLFragmentProcessor; 16eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualittclass GrProcessorKeyBuilder; 176251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 186251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon/** Provides custom fragment shader code. Fragment processors receive an input color (vec4f) and 196251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon produce an output color. They may reference textures and uniforms. They may use 206251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon GrCoordTransforms to receive a transformation of the local coordinates that map from local space 216251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon to the fragment being processed. 226251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon */ 236251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonclass GrFragmentProcessor : public GrProcessor { 246251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonpublic: 256251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon GrFragmentProcessor() 266251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon : INHERITED() 27290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt , fWillUseInputColor(true) 28290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt , fUsesLocalCoords(false) {} 296251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 30eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt /** Implemented using GLFragmentProcessor::GenKey as described in this class's comment. */ 31cfc18867d982119d9dc2888bf09f1093012daaddjvanverth virtual void getGLProcessorKey(const GrGLSLCaps& caps, 32eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt GrProcessorKeyBuilder* b) const = 0; 33eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 34eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt /** Returns a new instance of the appropriate *GL* implementation class 35eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt for the given GrFragmentProcessor; caller is responsible for deleting 36eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt the object. */ 37eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt virtual GrGLFragmentProcessor* createGLInstance() const = 0; 38eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt 39eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt /** Human-meaningful string to identify this GrFragmentProcessor; may be embedded 40eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt in generated shader code. */ 41eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt virtual const char* name() const = 0; 426251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 436251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon int numTransforms() const { return fCoordTransforms.count(); } 446251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 456251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon /** Returns the coordinate transformation at index. index must be valid according to 466251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon numTransforms(). */ 476251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; } 486251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 49abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt const SkTArray<const GrCoordTransform*, true>& coordTransforms() const { 50abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt return fCoordTransforms; 51abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt } 52abb52a1a70a81915c6196e0fb3e9bcb05e8be14djoshualitt 536251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon /** Will this prceossor read the source color value? */ 546251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon bool willUseInputColor() const { return fWillUseInputColor; } 556251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 56290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt /** Do any of the coordtransforms for this processor require local coords? */ 57290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool usesLocalCoords() const { return fUsesLocalCoords; } 58290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt 59eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt /** Returns true if this and other processor conservatively draw identically. It can only return 60eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt true when the two processor are of the same subclass (i.e. they return the same object from 616251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon from getFactory()). 626251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 63eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt A return value of true from isEqual() should not be used to test whether the processor would 64eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt generate the same shader code. To test for identical code generation use getGLProcessorKey*/ 65420d7e9a79358908850c74192b4949375563449absalomon bool isEqual(const GrFragmentProcessor& that) const { 66eb2a6761654307e8aeeeaabdd63c6bf9ab0411e9joshualitt if (this->classID() != that.classID() || 67420d7e9a79358908850c74192b4949375563449absalomon !this->hasSameTransforms(that) || 68420d7e9a79358908850c74192b4949375563449absalomon !this->hasSameTextureAccesses(that)) { 696251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon return false; 706251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon } 71420d7e9a79358908850c74192b4949375563449absalomon return this->onIsEqual(that); 726251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon } 736251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 7456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt /** 7556995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * This function is used to perform optimizations. When called the invarientOuput param 7656995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * indicate whether the input components to this processor in the FS will have known values. 7756995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * In inout the validFlags member is a bitfield of GrColorComponentFlags. The isSingleComponent 7856995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * member indicates whether the input will be 1 or 4 bytes. The function updates the members of 7956995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * inout to indicate known values of its output. A component of the color member only has 8056995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * meaning if the corresponding bit in validFlags is set. 8156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt */ 8256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt void computeInvariantOutput(GrInvariantOutput* inout) const; 8356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt 846251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonprotected: 856251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon /** 866251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * Fragment Processor subclasses call this from their constructor to register coordinate 87de258cd6b402c4da78b66e88191ad02162d87916bsalomon * transformations. Coord transforms provide a mechanism for a processor to receive coordinates 88de258cd6b402c4da78b66e88191ad02162d87916bsalomon * in their FS code. The matrix expresses a transformation from local space. For a given 89de258cd6b402c4da78b66e88191ad02162d87916bsalomon * fragment the matrix will be applied to the local coordinate that maps to the fragment. 90de258cd6b402c4da78b66e88191ad02162d87916bsalomon * 91de258cd6b402c4da78b66e88191ad02162d87916bsalomon * When the transformation has perspective, the transformed coordinates will have 92de258cd6b402c4da78b66e88191ad02162d87916bsalomon * 3 components. Otherwise they'll have 2. 93de258cd6b402c4da78b66e88191ad02162d87916bsalomon * 94de258cd6b402c4da78b66e88191ad02162d87916bsalomon * This must only be called from the constructor because GrProcessors are immutable. The 95de258cd6b402c4da78b66e88191ad02162d87916bsalomon * processor subclass manages the lifetime of the transformations (this function only stores a 96de258cd6b402c4da78b66e88191ad02162d87916bsalomon * pointer). The GrCoordTransform is typically a member field of the GrProcessor subclass. 97de258cd6b402c4da78b66e88191ad02162d87916bsalomon * 98de258cd6b402c4da78b66e88191ad02162d87916bsalomon * A processor subclass that has multiple methods of construction should always add its coord 99de258cd6b402c4da78b66e88191ad02162d87916bsalomon * transforms in a consistent order. The non-virtual implementation of isEqual() automatically 100de258cd6b402c4da78b66e88191ad02162d87916bsalomon * compares transforms and will assume they line up across the two processor instances. 1016251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon */ 1026251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon void addCoordTransform(const GrCoordTransform*); 1036251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 1046251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon /** 1056251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * If the prceossor will generate a result that does not depend on the input color value then it 1066251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * must call this function from its constructor. Otherwise, when its generated backend-specific 1076251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon * code might fail during variable binding due to unused variables. 1086251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon */ 1096251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon void setWillNotUseInputColor() { fWillUseInputColor = false; } 1106251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 11156995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt /** 11256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt * Subclass implements this to support getConstantColorComponents(...). 11356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt */ 11456995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const = 0; 11556995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt 1166251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomonprivate: 117de258cd6b402c4da78b66e88191ad02162d87916bsalomon /** 118de258cd6b402c4da78b66e88191ad02162d87916bsalomon * Subclass implements this to support isEqual(). It will only be called if it is known that 119de258cd6b402c4da78b66e88191ad02162d87916bsalomon * the two processors are of the same subclass (i.e. they return the same object from 120de258cd6b402c4da78b66e88191ad02162d87916bsalomon * getFactory()). The processor subclass should not compare its coord transforms as that will 121de258cd6b402c4da78b66e88191ad02162d87916bsalomon * be performed automatically in the non-virtual isEqual(). 122de258cd6b402c4da78b66e88191ad02162d87916bsalomon */ 123de258cd6b402c4da78b66e88191ad02162d87916bsalomon virtual bool onIsEqual(const GrFragmentProcessor&) const = 0; 124de258cd6b402c4da78b66e88191ad02162d87916bsalomon 125de258cd6b402c4da78b66e88191ad02162d87916bsalomon bool hasSameTransforms(const GrFragmentProcessor&) const; 1266251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 1276251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms; 1286251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon bool fWillUseInputColor; 129290c09b8bbd8d221d363150e2ce87158f4668df0joshualitt bool fUsesLocalCoords; 1306251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 1316251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon typedef GrProcessor INHERITED; 1326251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon}; 1336251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon 1346251d17dfadbbeba8a7e72affde5cbdbd0c0c95fbsalomon#endif 135