| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright 2014 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 GrXferProcessor_DEFINED | 
|  | 9 | #define GrXferProcessor_DEFINED | 
|  | 10 |  | 
| cdalton | ee0175f | 2015-06-12 08:21:26 -0700 | [diff] [blame] | 11 | #include "GrBlend.h" | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 12 | #include "GrColor.h" | 
| Brian Salomon | d61c9d9 | 2017-04-10 10:54:25 -0400 | [diff] [blame] | 13 | #include "GrNonAtomicRef.h" | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 14 | #include "GrProcessor.h" | 
| Hal Canary | ce78bad | 2017-05-04 14:15:40 -0400 | [diff] [blame] | 15 | #include "GrProcessorAnalysis.h" | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 16 | #include "GrTypes.h" | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 17 |  | 
| egdaniel | fa4cc8b | 2015-11-13 08:34:52 -0800 | [diff] [blame] | 18 | class GrGLSLXferProcessor; | 
| Hal Canary | ce78bad | 2017-05-04 14:15:40 -0400 | [diff] [blame] | 19 | class GrProcessorSet; | 
|  | 20 | class GrShaderCaps; | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 21 |  | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 22 | /** | 
| cdalton | 9954bc3 | 2015-04-29 14:17:00 -0700 | [diff] [blame] | 23 | * Barriers for blending. When a shader reads the dst directly, an Xfer barrier is sometimes | 
|  | 24 | * required after a pixel has been written, before it can be safely read again. | 
|  | 25 | */ | 
|  | 26 | enum GrXferBarrierType { | 
| bsalomon | cb02b38 | 2015-08-12 11:14:50 -0700 | [diff] [blame] | 27 | kNone_GrXferBarrierType = 0, //<! No barrier is required | 
|  | 28 | kTexture_GrXferBarrierType,  //<! Required when a shader reads and renders to the same texture. | 
|  | 29 | kBlend_GrXferBarrierType,    //<! Required by certain blend extensions. | 
| cdalton | 9954bc3 | 2015-04-29 14:17:00 -0700 | [diff] [blame] | 30 | }; | 
| bsalomon | cb02b38 | 2015-08-12 11:14:50 -0700 | [diff] [blame] | 31 | /** Should be able to treat kNone as false in boolean expressions */ | 
|  | 32 | GR_STATIC_ASSERT(SkToBool(kNone_GrXferBarrierType) == false); | 
| cdalton | 9954bc3 | 2015-04-29 14:17:00 -0700 | [diff] [blame] | 33 |  | 
|  | 34 | /** | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 35 | * GrXferProcessor is responsible for implementing the xfer mode that blends the src color and dst | 
| cdalton | edbb31f | 2015-06-08 12:14:44 -0700 | [diff] [blame] | 36 | * color, and for applying any coverage. It does this by emitting fragment shader code and | 
|  | 37 | * controlling the fixed-function blend state. When dual-source blending is available, it may also | 
|  | 38 | * write a seconday fragment shader output color. GrXferProcessor has two modes of operation: | 
|  | 39 | * | 
|  | 40 | * Dst read: When allowed by the backend API, or when supplied a texture of the destination, the | 
|  | 41 | * GrXferProcessor may read the destination color. While operating in this mode, the subclass only | 
|  | 42 | * provides shader code that blends the src and dst colors, and the base class applies coverage. | 
|  | 43 | * | 
|  | 44 | * No dst read: When not performing a dst read, the subclass is given full control of the fixed- | 
|  | 45 | * function blend state and/or secondary output, and is responsible to apply coverage on its own. | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 46 | * | 
|  | 47 | * A GrXferProcessor is never installed directly into our draw state, but instead is created from a | 
|  | 48 | * GrXPFactory once we have finalized the state of our draw. | 
|  | 49 | */ | 
| Brian Salomon | d61c9d9 | 2017-04-10 10:54:25 -0400 | [diff] [blame] | 50 | class GrXferProcessor : public GrProcessor, public GrNonAtomicRef<GrXferProcessor> { | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 51 | public: | 
|  | 52 | /** | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 53 | * A texture that contains the dst pixel values and an integer coord offset from device space | 
|  | 54 | * to the space of the texture. Depending on GPU capabilities a DstTexture may be used by a | 
|  | 55 | * GrXferProcessor for blending in the fragment shader. | 
|  | 56 | */ | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 57 | class DstProxy { | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 58 | public: | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 59 | DstProxy() { fOffset.set(0, 0); } | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 60 |  | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 61 | DstProxy(const DstProxy& other) { | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 62 | *this = other; | 
|  | 63 | } | 
|  | 64 |  | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 65 | DstProxy(sk_sp<GrTextureProxy> proxy, const SkIPoint& offset) | 
|  | 66 | : fProxy(std::move(proxy)) { | 
|  | 67 | if (fProxy) { | 
|  | 68 | fOffset = offset; | 
|  | 69 | } else { | 
|  | 70 | fOffset.set(0, 0); | 
|  | 71 | } | 
|  | 72 | } | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 73 |  | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 74 | DstProxy& operator=(const DstProxy& other) { | 
|  | 75 | fProxy = other.fProxy; | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 76 | fOffset = other.fOffset; | 
|  | 77 | return *this; | 
|  | 78 | } | 
|  | 79 |  | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 80 | bool operator==(const DstProxy& that) const { | 
|  | 81 | return fProxy == that.fProxy && fOffset == that.fOffset; | 
| Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 82 | } | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 83 | bool operator!=(const DstProxy& that) const { return !(*this == that); } | 
| Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 84 |  | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 85 | const SkIPoint& offset() const { return fOffset; } | 
|  | 86 |  | 
|  | 87 | void setOffset(const SkIPoint& offset) { fOffset = offset; } | 
|  | 88 | void setOffset(int ox, int oy) { fOffset.set(ox, oy); } | 
|  | 89 |  | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 90 | GrTextureProxy* proxy() const { return fProxy.get(); } | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 91 |  | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 92 | void setProxy(sk_sp<GrTextureProxy> proxy) { | 
|  | 93 | fProxy = std::move(proxy); | 
|  | 94 | if (!fProxy) { | 
| Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 95 | fOffset = {0, 0}; | 
|  | 96 | } | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 97 | } | 
|  | 98 |  | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 99 | bool instantiate(GrResourceProvider* resourceProvider) { | 
|  | 100 | return SkToBool(fProxy->instantiate(resourceProvider)); | 
|  | 101 | } | 
|  | 102 |  | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 103 | private: | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 104 | sk_sp<GrTextureProxy> fProxy; | 
|  | 105 | SkIPoint              fOffset; | 
| bsalomon | 6a44c6a | 2015-05-26 09:49:05 -0700 | [diff] [blame] | 106 | }; | 
|  | 107 |  | 
|  | 108 | /** | 
| egdaniel | 57d3b03 | 2015-11-13 11:57:27 -0800 | [diff] [blame] | 109 | * Sets a unique key on the GrProcessorKeyBuilder calls onGetGLSLProcessorKey(...) to get the | 
| bsalomon | 50785a3 | 2015-02-06 07:02:37 -0800 | [diff] [blame] | 110 | * specific subclass's key. | 
| Brian Salomon | 18dfa98 | 2017-04-03 16:57:43 -0400 | [diff] [blame] | 111 | */ | 
|  | 112 | void getGLSLProcessorKey(const GrShaderCaps&, | 
|  | 113 | GrProcessorKeyBuilder*, | 
|  | 114 | const GrSurfaceOrigin* originIfDstTexture) const; | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 115 |  | 
|  | 116 | /** Returns a new instance of the appropriate *GL* implementation class | 
|  | 117 | for the given GrXferProcessor; caller is responsible for deleting | 
|  | 118 | the object. */ | 
| egdaniel | 57d3b03 | 2015-11-13 11:57:27 -0800 | [diff] [blame] | 119 | virtual GrGLSLXferProcessor* createGLSLInstance() const = 0; | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 120 |  | 
|  | 121 | /** | 
| Brian Salomon | 18dfa98 | 2017-04-03 16:57:43 -0400 | [diff] [blame] | 122 | * Returns the barrier type, if any, that this XP will require. Note that the possibility | 
|  | 123 | * that a kTexture type barrier is required is handled by the GrPipeline and need not be | 
|  | 124 | * considered by subclass overrides of this function. | 
| cdalton | 9954bc3 | 2015-04-29 14:17:00 -0700 | [diff] [blame] | 125 | */ | 
| Brian Salomon | 18dfa98 | 2017-04-03 16:57:43 -0400 | [diff] [blame] | 126 | virtual GrXferBarrierType xferBarrierType(const GrCaps& caps) const { | 
|  | 127 | return kNone_GrXferBarrierType; | 
|  | 128 | } | 
| cdalton | 9954bc3 | 2015-04-29 14:17:00 -0700 | [diff] [blame] | 129 |  | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 130 | struct BlendInfo { | 
| cdalton | f4f2b44 | 2015-04-23 09:40:23 -0700 | [diff] [blame] | 131 | void reset() { | 
| cdalton | 8917d62 | 2015-05-06 13:40:21 -0700 | [diff] [blame] | 132 | fEquation = kAdd_GrBlendEquation; | 
| cdalton | f4f2b44 | 2015-04-23 09:40:23 -0700 | [diff] [blame] | 133 | fSrcBlend = kOne_GrBlendCoeff; | 
|  | 134 | fDstBlend = kZero_GrBlendCoeff; | 
|  | 135 | fBlendConstant = 0; | 
|  | 136 | fWriteColor = true; | 
|  | 137 | } | 
| egdaniel | 080e673 | 2014-12-22 07:35:52 -0800 | [diff] [blame] | 138 |  | 
| bsalomon | f7cc877 | 2015-05-11 11:21:14 -0700 | [diff] [blame] | 139 | SkDEBUGCODE(SkString dump() const;) | 
|  | 140 |  | 
| cdalton | 8917d62 | 2015-05-06 13:40:21 -0700 | [diff] [blame] | 141 | GrBlendEquation fEquation; | 
|  | 142 | GrBlendCoeff    fSrcBlend; | 
|  | 143 | GrBlendCoeff    fDstBlend; | 
|  | 144 | GrColor         fBlendConstant; | 
|  | 145 | bool            fWriteColor; | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 146 | }; | 
|  | 147 |  | 
| cdalton | edbb31f | 2015-06-08 12:14:44 -0700 | [diff] [blame] | 148 | void getBlendInfo(BlendInfo* blendInfo) const; | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 149 |  | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 150 | bool willReadDstColor() const { return fWillReadDstColor; } | 
|  | 151 |  | 
| bsalomon | 50785a3 | 2015-02-06 07:02:37 -0800 | [diff] [blame] | 152 | /** | 
| cdalton | 86ae0a9 | 2015-06-08 15:11:04 -0700 | [diff] [blame] | 153 | * If we are performing a dst read, returns whether the base class will use mixed samples to | 
|  | 154 | * antialias the shader's final output. If not doing a dst read, the subclass is responsible | 
|  | 155 | * for antialiasing and this returns false. | 
|  | 156 | */ | 
|  | 157 | bool dstReadUsesMixedSamples() const { return fDstReadUsesMixedSamples; } | 
|  | 158 |  | 
|  | 159 | /** | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 160 | * Returns whether or not this xferProcossor will set a secondary output to be used with dual | 
|  | 161 | * source blending. | 
|  | 162 | */ | 
| cdalton | edbb31f | 2015-06-08 12:14:44 -0700 | [diff] [blame] | 163 | bool hasSecondaryOutput() const; | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 164 |  | 
| Greg Daniel | 6ebe4b9 | 2017-05-19 10:56:46 -0400 | [diff] [blame] | 165 | bool isLCD() const { return fIsLCD; } | 
|  | 166 |  | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 167 | /** Returns true if this and other processor conservatively draw identically. It can only return | 
|  | 168 | true when the two processor are of the same subclass (i.e. they return the same object from | 
|  | 169 | from getFactory()). | 
|  | 170 |  | 
|  | 171 | A return value of true from isEqual() should not be used to test whether the processor would | 
| egdaniel | 57d3b03 | 2015-11-13 11:57:27 -0800 | [diff] [blame] | 172 | generate the same shader code. To test for identical code generation use getGLSLProcessorKey | 
|  | 173 | */ | 
| Greg Daniel | 6ebe4b9 | 2017-05-19 10:56:46 -0400 | [diff] [blame] | 174 |  | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 175 | bool isEqual(const GrXferProcessor& that) const { | 
|  | 176 | if (this->classID() != that.classID()) { | 
|  | 177 | return false; | 
|  | 178 | } | 
| bsalomon | 50785a3 | 2015-02-06 07:02:37 -0800 | [diff] [blame] | 179 | if (this->fWillReadDstColor != that.fWillReadDstColor) { | 
|  | 180 | return false; | 
|  | 181 | } | 
| cdalton | 86ae0a9 | 2015-06-08 15:11:04 -0700 | [diff] [blame] | 182 | if (this->fDstReadUsesMixedSamples != that.fDstReadUsesMixedSamples) { | 
|  | 183 | return false; | 
|  | 184 | } | 
| Greg Daniel | 6ebe4b9 | 2017-05-19 10:56:46 -0400 | [diff] [blame] | 185 | if (fIsLCD != that.fIsLCD) { | 
|  | 186 | return false; | 
|  | 187 | } | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 188 | return this->onIsEqual(that); | 
|  | 189 | } | 
| Brian Salomon | 92aee3d | 2016-12-21 09:20:25 -0500 | [diff] [blame] | 190 |  | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 191 | protected: | 
| Ethan Nicholas | abff956 | 2017-10-09 10:54:08 -0400 | [diff] [blame] | 192 | GrXferProcessor(ClassID classID); | 
|  | 193 | GrXferProcessor(ClassID classID, bool willReadDstColor, bool hasMixedSamples, | 
|  | 194 | GrProcessorAnalysisCoverage); | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 195 |  | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 196 | private: | 
| bsalomon | 50785a3 | 2015-02-06 07:02:37 -0800 | [diff] [blame] | 197 | /** | 
|  | 198 | * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this xfer | 
|  | 199 | * processor's GL backend implementation. | 
|  | 200 | */ | 
| Brian Salomon | 94efbf5 | 2016-11-29 13:43:05 -0500 | [diff] [blame] | 201 | virtual void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0; | 
| bsalomon | 50785a3 | 2015-02-06 07:02:37 -0800 | [diff] [blame] | 202 |  | 
| cdalton | f4f2b44 | 2015-04-23 09:40:23 -0700 | [diff] [blame] | 203 | /** | 
| cdalton | edbb31f | 2015-06-08 12:14:44 -0700 | [diff] [blame] | 204 | * If we are not performing a dst read, returns whether the subclass will set a secondary | 
| cdalton | 86ae0a9 | 2015-06-08 15:11:04 -0700 | [diff] [blame] | 205 | * output. When using dst reads, the base class controls the secondary output and this method | 
| cdalton | edbb31f | 2015-06-08 12:14:44 -0700 | [diff] [blame] | 206 | * will not be called. | 
|  | 207 | */ | 
|  | 208 | virtual bool onHasSecondaryOutput() const { return false; } | 
|  | 209 |  | 
|  | 210 | /** | 
|  | 211 | * If we are not performing a dst read, retrieves the fixed-function blend state required by the | 
| cdalton | 86ae0a9 | 2015-06-08 15:11:04 -0700 | [diff] [blame] | 212 | * subclass. When using dst reads, the base class controls the fixed-function blend state and | 
|  | 213 | * this method will not be called. The BlendInfo struct comes initialized to "no blending". | 
| cdalton | f4f2b44 | 2015-04-23 09:40:23 -0700 | [diff] [blame] | 214 | */ | 
|  | 215 | virtual void onGetBlendInfo(BlendInfo*) const {} | 
|  | 216 |  | 
| egdaniel | c230414 | 2014-12-11 13:15:13 -0800 | [diff] [blame] | 217 | virtual bool onIsEqual(const GrXferProcessor&) const = 0; | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 218 |  | 
| Greg Daniel | 6ebe4b9 | 2017-05-19 10:56:46 -0400 | [diff] [blame] | 219 | bool fWillReadDstColor; | 
|  | 220 | bool fDstReadUsesMixedSamples; | 
|  | 221 | bool fIsLCD; | 
| egdaniel | 9513143 | 2014-12-09 11:15:43 -0800 | [diff] [blame] | 222 |  | 
| Ethan Nicholas | abff956 | 2017-10-09 10:54:08 -0400 | [diff] [blame] | 223 | typedef GrProcessor INHERITED; | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 224 | }; | 
|  | 225 |  | 
|  | 226 | /** | 
|  | 227 | * We install a GrXPFactory (XPF) early on in the pipeline before all the final draw information is | 
|  | 228 | * known (e.g. whether there is fractional pixel coverage, will coverage be 1 or 4 channel, is the | 
|  | 229 | * draw opaque, etc.). Once the state of the draw is finalized, we use the XPF along with all the | 
|  | 230 | * draw information to create a GrXferProcessor (XP) which can implement the desired blending for | 
|  | 231 | * the draw. | 
|  | 232 | * | 
|  | 233 | * Before the XP is created, the XPF is able to answer queries about what functionality the XPs it | 
|  | 234 | * creates will have. For example, can it create an XP that supports RGB coverage or will the XP | 
|  | 235 | * blend with the destination color. | 
| Brian Salomon | a163392 | 2017-01-09 11:46:10 -0500 | [diff] [blame] | 236 | * | 
|  | 237 | * GrXPFactories are intended to be static immutable objects. We pass them around as raw pointers | 
|  | 238 | * and expect the pointers to always be valid and for the factories to be reusable and thread safe. | 
|  | 239 | * Equality is tested for using pointer comparison. GrXPFactory destructors must be no-ops. | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 240 | */ | 
| Brian Salomon | a163392 | 2017-01-09 11:46:10 -0500 | [diff] [blame] | 241 |  | 
|  | 242 | // In order to construct GrXPFactory subclass instances as constexpr the subclass, and therefore | 
|  | 243 | // GrXPFactory, must be a literal type. One requirement is having a trivial destructor. This is ok | 
|  | 244 | // since these objects have no need for destructors. However, GCC and clang throw a warning when a | 
|  | 245 | // class has virtual functions and a non-virtual destructor. We suppress that warning here and | 
|  | 246 | // for the subclasses. | 
| Chris Dalton | 1ef8094 | 2017-12-04 12:01:30 -0700 | [diff] [blame] | 247 | #if defined(__GNUC__) | 
| Brian Salomon | a163392 | 2017-01-09 11:46:10 -0500 | [diff] [blame] | 248 | #pragma GCC diagnostic push | 
|  | 249 | #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" | 
|  | 250 | #endif | 
| Chris Dalton | 1ef8094 | 2017-12-04 12:01:30 -0700 | [diff] [blame] | 251 | #if defined(__clang__) | 
|  | 252 | #pragma clang diagnostic push | 
|  | 253 | #pragma clang diagnostic ignored "-Wnon-virtual-dtor" | 
|  | 254 | #endif | 
| Brian Salomon | a163392 | 2017-01-09 11:46:10 -0500 | [diff] [blame] | 255 | class GrXPFactory { | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 256 | public: | 
| Robert Phillips | bb581ce | 2017-05-29 15:05:15 -0400 | [diff] [blame] | 257 | typedef GrXferProcessor::DstProxy DstProxy; | 
| Brian Salomon | 5be6c95 | 2017-01-20 19:06:29 +0000 | [diff] [blame] | 258 |  | 
| Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 259 | enum class AnalysisProperties : unsigned { | 
|  | 260 | kNone = 0x0, | 
| Brian Salomon | 4fc7740 | 2017-03-30 16:48:26 -0400 | [diff] [blame] | 261 | /** | 
|  | 262 | * The fragment shader will require the destination color. | 
|  | 263 | */ | 
| Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 264 | kReadsDstInShader = 0x1, | 
| Brian Salomon | 4fc7740 | 2017-03-30 16:48:26 -0400 | [diff] [blame] | 265 | /** | 
|  | 266 | * The op may apply coverage as alpha and still blend correctly. | 
|  | 267 | */ | 
|  | 268 | kCompatibleWithAlphaAsCoverage = 0x2, | 
|  | 269 | /** | 
|  | 270 | * The color input to the GrXferProcessor will be ignored. | 
|  | 271 | */ | 
|  | 272 | kIgnoresInputColor = 0x4, | 
|  | 273 | /** | 
|  | 274 | * If set overlapping stencil and cover operations can be replaced by a combined stencil | 
|  | 275 | * followed by a combined cover. | 
|  | 276 | */ | 
|  | 277 | kCanCombineOverlappedStencilAndCover = 0x8, | 
|  | 278 | /** | 
|  | 279 | * The destination color will be provided to the fragment processor using a texture. This is | 
|  | 280 | * additional information about the implementation of kReadsDstInShader. | 
|  | 281 | */ | 
|  | 282 | kRequiresDstTexture = 0x10, | 
|  | 283 | /** | 
|  | 284 | * If set overlapping draws may not be combined because a barrier must be inserted between | 
|  | 285 | * them. | 
|  | 286 | */ | 
|  | 287 | kRequiresBarrierBetweenOverlappingDraws = 0x20, | 
| Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 288 | }; | 
|  | 289 | GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(AnalysisProperties); | 
| egdaniel | 080e673 | 2014-12-22 07:35:52 -0800 | [diff] [blame] | 290 |  | 
| Brian Salomon | d61c9d9 | 2017-04-10 10:54:25 -0400 | [diff] [blame] | 291 | static sk_sp<const GrXferProcessor> MakeXferProcessor(const GrXPFactory*, | 
|  | 292 | const GrProcessorAnalysisColor&, | 
|  | 293 | GrProcessorAnalysisCoverage, | 
|  | 294 | bool hasMixedSamples, | 
| Brian Osman | 9a725dd | 2017-09-20 09:53:22 -0400 | [diff] [blame] | 295 | const GrCaps& caps, | 
|  | 296 | GrPixelConfigIsClamped dstIsClamped); | 
| Brian Salomon | a076d87 | 2017-04-04 15:17:03 -0400 | [diff] [blame] | 297 |  | 
| Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 298 | static AnalysisProperties GetAnalysisProperties(const GrXPFactory*, | 
| Brian Salomon | a811b12 | 2017-03-30 08:21:32 -0400 | [diff] [blame] | 299 | const GrProcessorAnalysisColor&, | 
|  | 300 | const GrProcessorAnalysisCoverage&, | 
| Brian Osman | 9a725dd | 2017-09-20 09:53:22 -0400 | [diff] [blame] | 301 | const GrCaps&, | 
|  | 302 | GrPixelConfigIsClamped); | 
| Brian Salomon | 54d212e | 2017-03-21 14:22:38 -0400 | [diff] [blame] | 303 |  | 
| egdaniel | 915187b | 2014-12-05 12:58:28 -0800 | [diff] [blame] | 304 | protected: | 
| Brian Salomon | a163392 | 2017-01-09 11:46:10 -0500 | [diff] [blame] | 305 | constexpr GrXPFactory() {} | 
| egdaniel | 915187b | 2014-12-05 12:58:28 -0800 | [diff] [blame] | 306 |  | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 307 | private: | 
| Brian Salomon | d61c9d9 | 2017-04-10 10:54:25 -0400 | [diff] [blame] | 308 | virtual sk_sp<const GrXferProcessor> makeXferProcessor(const GrProcessorAnalysisColor&, | 
|  | 309 | GrProcessorAnalysisCoverage, | 
|  | 310 | bool hasMixedSamples, | 
| Brian Osman | 9a725dd | 2017-09-20 09:53:22 -0400 | [diff] [blame] | 311 | const GrCaps&, | 
|  | 312 | GrPixelConfigIsClamped) const = 0; | 
| ethannicholas | 2279325 | 2016-01-30 09:59:10 -0800 | [diff] [blame] | 313 |  | 
| bsalomon | 50785a3 | 2015-02-06 07:02:37 -0800 | [diff] [blame] | 314 | /** | 
| Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 315 | * Subclass analysis implementation. This should not return kNeedsDstInTexture as that will be | 
|  | 316 | * inferred by the base class based on kReadsDstInShader and the caps. | 
| bsalomon | 50785a3 | 2015-02-06 07:02:37 -0800 | [diff] [blame] | 317 | */ | 
| Brian Salomon | a811b12 | 2017-03-30 08:21:32 -0400 | [diff] [blame] | 318 | virtual AnalysisProperties analysisProperties(const GrProcessorAnalysisColor&, | 
|  | 319 | const GrProcessorAnalysisCoverage&, | 
| Brian Osman | 9a725dd | 2017-09-20 09:53:22 -0400 | [diff] [blame] | 320 | const GrCaps&, | 
|  | 321 | GrPixelConfigIsClamped) const = 0; | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 322 | }; | 
| Chris Dalton | 1ef8094 | 2017-12-04 12:01:30 -0700 | [diff] [blame] | 323 | #if defined(__GNUC__) | 
| Brian Salomon | a163392 | 2017-01-09 11:46:10 -0500 | [diff] [blame] | 324 | #pragma GCC diagnostic pop | 
|  | 325 | #endif | 
| Chris Dalton | 1ef8094 | 2017-12-04 12:01:30 -0700 | [diff] [blame] | 326 | #if defined(__clang__) | 
|  | 327 | #pragma clang diagnostic pop | 
|  | 328 | #endif | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 329 |  | 
| Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 330 | GR_MAKE_BITFIELD_CLASS_OPS(GrXPFactory::AnalysisProperties); | 
| egdaniel | 378092f | 2014-12-03 10:40:13 -0800 | [diff] [blame] | 331 |  | 
| Brian Salomon | 3185384 | 2017-03-28 16:32:05 -0400 | [diff] [blame] | 332 | #endif |