| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2014 Google Inc. | 2  * Copyright 2014 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "effects/GrPorterDuffXferProcessor.h" | 8 #include "effects/GrPorterDuffXferProcessor.h" | 
| 9 | 9 | 
| 10 #include "GrBlend.h" | 10 #include "GrBlend.h" | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 114 void GrPorterDuffXferProcessor::onComputeInvariantOutput(GrInvariantOutput* inou
     t) const { | 114 void GrPorterDuffXferProcessor::onComputeInvariantOutput(GrInvariantOutput* inou
     t) const { | 
| 115     inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); | 115     inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); | 
| 116 } | 116 } | 
| 117 | 117 | 
| 118 GrXferProcessor::OptFlags | 118 GrXferProcessor::OptFlags | 
| 119 GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, | 119 GrPorterDuffXferProcessor::getOptimizations(const GrProcOptInfo& colorPOI, | 
| 120                                             const GrProcOptInfo& coveragePOI, | 120                                             const GrProcOptInfo& coveragePOI, | 
| 121                                             bool isCoverageDrawing, | 121                                             bool isCoverageDrawing, | 
| 122                                             bool colorWriteDisabled, | 122                                             bool colorWriteDisabled, | 
| 123                                             bool doesStencilWrite, | 123                                             bool doesStencilWrite, | 
| 124                                             GrColor* color, uint8_t* coverage, | 124                                             GrColor* overrideColor, | 
|  | 125                                             uint8_t* overrideCoverage, | 
| 125                                             const GrDrawTargetCaps& caps) { | 126                                             const GrDrawTargetCaps& caps) { | 
| 126     GrXferProcessor::OptFlags optFlags = this->internalGetOptimizations(colorPOI
     , | 127     GrXferProcessor::OptFlags optFlags; | 
| 127                                                                         coverage
     POI, | 128     // Optimizations when doing RGB Coverage | 
| 128                                                                         isCovera
     geDrawing, | 129     if (coveragePOI.isFourChannelOutput()) { | 
| 129                                                                         colorWri
     teDisabled, | 130         // We want to force our primary output to be alpha * Coverage, where alp
     ha is the alpha | 
| 130                                                                         doesSten
     cilWrite, | 131         // value of the blend the constant. We should already have valid blend c
     oeff's if we are at | 
| 131                                                                         color, | 132         // a point where we have RGB coverage. We don't need any color stages si
     nce the known color | 
| 132                                                                         coverage
     ); | 133         // output is already baked into the blendConstant. | 
| 133 | 134         uint8_t alpha = GrColorUnpackA(fBlendConstant); | 
|  | 135         *overrideColor = GrColorPackRGBA(alpha, alpha, alpha, alpha); | 
|  | 136         optFlags = GrXferProcessor::kOverrideColor_OptFlag; | 
|  | 137     } else { | 
|  | 138         optFlags = this->internalGetOptimizations(colorPOI, | 
|  | 139                                                   coveragePOI, | 
|  | 140                                                   isCoverageDrawing, | 
|  | 141                                                   colorWriteDisabled, | 
|  | 142                                                   doesStencilWrite, | 
|  | 143                                                   overrideColor, | 
|  | 144                                                   overrideCoverage); | 
|  | 145     } | 
| 134     this->calcOutputTypes(optFlags, caps, isCoverageDrawing || coveragePOI.isSol
     idWhite(), | 146     this->calcOutputTypes(optFlags, caps, isCoverageDrawing || coveragePOI.isSol
     idWhite(), | 
| 135                           colorPOI.readsDst() || coveragePOI.readsDst()); | 147                           colorPOI.readsDst() || coveragePOI.readsDst()); | 
| 136     return optFlags; | 148     return optFlags; | 
| 137 } | 149 } | 
| 138 | 150 | 
| 139 void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFla
     gs, | 151 void GrPorterDuffXferProcessor::calcOutputTypes(GrXferProcessor::OptFlags optFla
     gs, | 
| 140                                                 const GrDrawTargetCaps& caps, | 152                                                 const GrDrawTargetCaps& caps, | 
| 141                                                 bool hasSolidCoverage, bool read
     sDst) { | 153                                                 bool hasSolidCoverage, bool read
     sDst) { | 
| 142     // If we do have coverage determine whether it matters.  Dual source blendin
     g is expensive so | 154     // If we do have coverage determine whether it matters.  Dual source blendin
     g is expensive so | 
| 143     // we don't do it if we are doing coverage drawing.  If we aren't then We al
     ways do dual source | 155     // we don't do it if we are doing coverage drawing.  If we aren't then We al
     ways do dual source | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 165         } | 177         } | 
| 166     } | 178     } | 
| 167 } | 179 } | 
| 168 | 180 | 
| 169 GrXferProcessor::OptFlags | 181 GrXferProcessor::OptFlags | 
| 170 GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
     I, | 182 GrPorterDuffXferProcessor::internalGetOptimizations(const GrProcOptInfo& colorPO
     I, | 
| 171                                                     const GrProcOptInfo& coverag
     ePOI, | 183                                                     const GrProcOptInfo& coverag
     ePOI, | 
| 172                                                     bool isCoverageDrawing, | 184                                                     bool isCoverageDrawing, | 
| 173                                                     bool colorWriteDisabled, | 185                                                     bool colorWriteDisabled, | 
| 174                                                     bool doesStencilWrite, | 186                                                     bool doesStencilWrite, | 
| 175                                                     GrColor* color, uint8_t* cov
     erage) { | 187                                                     GrColor* overrideColor, | 
|  | 188                                                     uint8_t* overrideCoverage) { | 
| 176     if (colorWriteDisabled) { | 189     if (colorWriteDisabled) { | 
| 177         fSrcBlend = kZero_GrBlendCoeff; | 190         fSrcBlend = kZero_GrBlendCoeff; | 
| 178         fDstBlend = kOne_GrBlendCoeff; | 191         fDstBlend = kOne_GrBlendCoeff; | 
| 179     } | 192     } | 
| 180 | 193 | 
| 181     bool srcAIsOne; | 194     bool srcAIsOne; | 
| 182     bool hasCoverage; | 195     bool hasCoverage; | 
| 183     if (isCoverageDrawing) { | 196     if (isCoverageDrawing) { | 
| 184         srcAIsOne = colorPOI.isOpaque() && coveragePOI.isOpaque(); | 197         srcAIsOne = colorPOI.isOpaque() && coveragePOI.isOpaque(); | 
| 185         hasCoverage = false; | 198         hasCoverage = false; | 
| 186     } else { | 199     } else { | 
| 187         srcAIsOne = colorPOI.isOpaque(); | 200         srcAIsOne = colorPOI.isOpaque(); | 
| 188         hasCoverage = !coveragePOI.isSolidWhite(); | 201         hasCoverage = !coveragePOI.isSolidWhite(); | 
| 189     } | 202     } | 
| 190 | 203 | 
| 191     bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || | 204     bool dstCoeffIsOne = kOne_GrBlendCoeff == fDstBlend || | 
| 192                          (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); | 205                          (kSA_GrBlendCoeff == fDstBlend && srcAIsOne); | 
| 193     bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend || | 206     bool dstCoeffIsZero = kZero_GrBlendCoeff == fDstBlend || | 
| 194                          (kISA_GrBlendCoeff == fDstBlend && srcAIsOne); | 207                          (kISA_GrBlendCoeff == fDstBlend && srcAIsOne); | 
| 195 | 208 | 
| 196     // Optimizations when doing RGB Coverage |  | 
| 197     if (coveragePOI.isFourChannelOutput()) { |  | 
| 198         // We want to force our primary output to be alpha * Coverage, where alp
     ha is the alpha |  | 
| 199         // value of the blend the constant. We should already have valid blend c
     oeff's if we are at |  | 
| 200         // a point where we have RGB coverage. We don't need any color stages si
     nce the known color |  | 
| 201         // output is already baked into the blendConstant. |  | 
| 202         uint8_t alpha = GrColorUnpackA(fBlendConstant); |  | 
| 203         *color = GrColorPackRGBA(alpha, alpha, alpha, alpha); |  | 
| 204         return GrXferProcessor::kClearColorStages_OptFlag; |  | 
| 205     } |  | 
| 206 |  | 
| 207     // When coeffs are (0,1) there is no reason to draw at all, unless | 209     // When coeffs are (0,1) there is no reason to draw at all, unless | 
| 208     // stenciling is enabled. Having color writes disabled is effectively | 210     // stenciling is enabled. Having color writes disabled is effectively | 
| 209     // (0,1). | 211     // (0,1). | 
| 210     if ((kZero_GrBlendCoeff == fSrcBlend && dstCoeffIsOne)) { | 212     if ((kZero_GrBlendCoeff == fSrcBlend && dstCoeffIsOne)) { | 
| 211         if (doesStencilWrite) { | 213         if (doesStencilWrite) { | 
| 212             *color = 0xffffffff; | 214             *overrideColor = 0xffffffff; | 
| 213             return GrXferProcessor::kClearColorStages_OptFlag | | 215             return GrXferProcessor::kClearColorStages_OptFlag | | 
| 214                    GrXferProcessor::kSetCoverageDrawing_OptFlag; | 216                    GrXferProcessor::kSetCoverageDrawing_OptFlag; | 
| 215         } else { | 217         } else { | 
| 216             fDstBlend = kOne_GrBlendCoeff; | 218             fDstBlend = kOne_GrBlendCoeff; | 
| 217             return GrXferProcessor::kSkipDraw_OptFlag; | 219             return GrXferProcessor::kSkipDraw_OptFlag; | 
| 218         } | 220         } | 
| 219     } | 221     } | 
| 220 | 222 | 
| 221     // if we don't have coverage we can check whether the dst | 223     // if we don't have coverage we can check whether the dst | 
| 222     // has to read at all. If not, we'll disable blending. | 224     // has to read at all. If not, we'll disable blending. | 
| 223     if (!hasCoverage) { | 225     if (!hasCoverage) { | 
| 224         if (dstCoeffIsZero) { | 226         if (dstCoeffIsZero) { | 
| 225             if (kOne_GrBlendCoeff == fSrcBlend) { | 227             if (kOne_GrBlendCoeff == fSrcBlend) { | 
| 226                 // if there is no coverage and coeffs are (1,0) then we | 228                 // if there is no coverage and coeffs are (1,0) then we | 
| 227                 // won't need to read the dst at all, it gets replaced by src | 229                 // won't need to read the dst at all, it gets replaced by src | 
| 228                 fDstBlend = kZero_GrBlendCoeff; | 230                 fDstBlend = kZero_GrBlendCoeff; | 
| 229                 return GrXferProcessor::kNone_Opt; | 231                 return GrXferProcessor::kNone_Opt; | 
| 230             } else if (kZero_GrBlendCoeff == fSrcBlend) { | 232             } else if (kZero_GrBlendCoeff == fSrcBlend) { | 
| 231                 // if the op is "clear" then we don't need to emit a color | 233                 // if the op is "clear" then we don't need to emit a color | 
| 232                 // or blend, just write transparent black into the dst. | 234                 // or blend, just write transparent black into the dst. | 
| 233                 fSrcBlend = kOne_GrBlendCoeff; | 235                 fSrcBlend = kOne_GrBlendCoeff; | 
| 234                 fDstBlend = kZero_GrBlendCoeff; | 236                 fDstBlend = kZero_GrBlendCoeff; | 
| 235                 *color = 0; | 237                 *overrideColor = 0; | 
| 236                 *coverage = 0xff; | 238                 *overrideCoverage = 0xff; | 
| 237                 return GrXferProcessor::kClearColorStages_OptFlag | | 239                 return GrXferProcessor::kClearColorStages_OptFlag | | 
| 238                        GrXferProcessor::kClearCoverageStages_OptFlag; | 240                        GrXferProcessor::kClearCoverageStages_OptFlag; | 
| 239             } | 241             } | 
| 240         } | 242         } | 
| 241     } else if (isCoverageDrawing) { | 243     } else if (isCoverageDrawing) { | 
| 242         // we have coverage but we aren't distinguishing it from alpha by reques
     t. | 244         // we have coverage but we aren't distinguishing it from alpha by reques
     t. | 
| 243         return GrXferProcessor::kSetCoverageDrawing_OptFlag; | 245         return GrXferProcessor::kSetCoverageDrawing_OptFlag; | 
| 244     } else { | 246     } else { | 
| 245         // check whether coverage can be safely rolled into alpha | 247         // check whether coverage can be safely rolled into alpha | 
| 246         // of if we can skip color computation and just emit coverage | 248         // of if we can skip color computation and just emit coverage | 
| 247         if (can_tweak_alpha_for_coverage(fDstBlend, isCoverageDrawing)) { | 249         if (can_tweak_alpha_for_coverage(fDstBlend, isCoverageDrawing)) { | 
| 248             return GrXferProcessor::kSetCoverageDrawing_OptFlag; | 250             return GrXferProcessor::kSetCoverageDrawing_OptFlag; | 
| 249         } | 251         } | 
| 250         if (dstCoeffIsZero) { | 252         if (dstCoeffIsZero) { | 
| 251             if (kZero_GrBlendCoeff == fSrcBlend) { | 253             if (kZero_GrBlendCoeff == fSrcBlend) { | 
| 252                 // the source color is not included in the blend | 254                 // the source color is not included in the blend | 
| 253                 // the dst coeff is effectively zero so blend works out to: | 255                 // the dst coeff is effectively zero so blend works out to: | 
| 254                 // (c)(0)D + (1-c)D = (1-c)D. | 256                 // (c)(0)D + (1-c)D = (1-c)D. | 
| 255                 fDstBlend = kISA_GrBlendCoeff; | 257                 fDstBlend = kISA_GrBlendCoeff; | 
| 256                 *color = 0xffffffff; | 258                 *overrideColor = 0xffffffff; | 
| 257                 return GrXferProcessor::kClearColorStages_OptFlag | | 259                 return GrXferProcessor::kClearColorStages_OptFlag | | 
| 258                        GrXferProcessor::kSetCoverageDrawing_OptFlag; | 260                        GrXferProcessor::kSetCoverageDrawing_OptFlag; | 
| 259             } else if (srcAIsOne) { | 261             } else if (srcAIsOne) { | 
| 260                 // the dst coeff is effectively zero so blend works out to: | 262                 // the dst coeff is effectively zero so blend works out to: | 
| 261                 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. | 263                 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. | 
| 262                 // If Sa is 1 then we can replace Sa with c | 264                 // If Sa is 1 then we can replace Sa with c | 
| 263                 // and set dst coeff to 1-Sa. | 265                 // and set dst coeff to 1-Sa. | 
| 264                 fDstBlend = kISA_GrBlendCoeff; | 266                 fDstBlend = kISA_GrBlendCoeff; | 
| 265                 return GrXferProcessor::kSetCoverageDrawing_OptFlag; | 267                 return GrXferProcessor::kSetCoverageDrawing_OptFlag; | 
| 266             } | 268             } | 
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 549     } while (GrBlendCoeffRefsSrc(src)); | 551     } while (GrBlendCoeffRefsSrc(src)); | 
| 550 | 552 | 
| 551     GrBlendCoeff dst; | 553     GrBlendCoeff dst; | 
| 552     do { | 554     do { | 
| 553         dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub
     licGrBlendCoeff)); | 555         dst = GrBlendCoeff(random->nextRangeU(kFirstPublicGrBlendCoeff, kLastPub
     licGrBlendCoeff)); | 
| 554     } while (GrBlendCoeffRefsDst(dst)); | 556     } while (GrBlendCoeffRefsDst(dst)); | 
| 555 | 557 | 
| 556     return GrPorterDuffXPFactory::Create(src, dst); | 558     return GrPorterDuffXPFactory::Create(src, dst); | 
| 557 } | 559 } | 
| 558 | 560 | 
| OLD | NEW | 
|---|