Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: src/gpu/effects/GrPorterDuffXferProcessor.cpp

Issue 791933006: Add xp optimization for RGB coverage. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: nits2 Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrOptDrawState.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/gpu/GrOptDrawState.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698