| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "GrFragmentProcessor.h" | 8 #include "GrFragmentProcessor.h" |
| 9 #include "GrCoordTransform.h" | 9 #include "GrCoordTransform.h" |
| 10 #include "GrInvariantOutput.h" | 10 #include "GrInvariantOutput.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 // Can't add transforms after registering any children since their transform
s have already been | 82 // Can't add transforms after registering any children since their transform
s have already been |
| 83 // bubbled up into our fCoordTransforms array | 83 // bubbled up into our fCoordTransforms array |
| 84 SkASSERT(fChildProcessors.empty()); | 84 SkASSERT(fChildProcessors.empty()); |
| 85 | 85 |
| 86 fCoordTransforms.push_back(transform); | 86 fCoordTransforms.push_back(transform); |
| 87 fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_G
rCoordSet; | 87 fUsesLocalCoords = fUsesLocalCoords || transform->sourceCoords() == kLocal_G
rCoordSet; |
| 88 SkDEBUGCODE(transform->setInProcessor();) | 88 SkDEBUGCODE(transform->setInProcessor();) |
| 89 fNumTransformsExclChildren++; | 89 fNumTransformsExclChildren++; |
| 90 } | 90 } |
| 91 | 91 |
| 92 int GrFragmentProcessor::registerChildProcessor(const GrFragmentProcessor* child
) { | 92 int GrFragmentProcessor::registerChildProcessor(sk_sp<GrFragmentProcessor> child
) { |
| 93 // Append the child's transforms to our transforms array and the child's tex
tures array to our | 93 // Append the child's transforms to our transforms array and the child's tex
tures array to our |
| 94 // textures array | 94 // textures array |
| 95 if (!child->fCoordTransforms.empty()) { | 95 if (!child->fCoordTransforms.empty()) { |
| 96 fCoordTransforms.push_back_n(child->fCoordTransforms.count(), | 96 fCoordTransforms.push_back_n(child->fCoordTransforms.count(), |
| 97 child->fCoordTransforms.begin()); | 97 child->fCoordTransforms.begin()); |
| 98 } | 98 } |
| 99 if (!child->fTextureAccesses.empty()) { | 99 if (!child->fTextureAccesses.empty()) { |
| 100 fTextureAccesses.push_back_n(child->fTextureAccesses.count(), | 100 fTextureAccesses.push_back_n(child->fTextureAccesses.count(), |
| 101 child->fTextureAccesses.begin()); | 101 child->fTextureAccesses.begin()); |
| 102 } | 102 } |
| 103 | 103 |
| 104 int index = fChildProcessors.count(); | |
| 105 fChildProcessors.push_back(SkRef(child)); | |
| 106 | |
| 107 this->combineRequiredFeatures(*child); | 104 this->combineRequiredFeatures(*child); |
| 108 | 105 |
| 109 if (child->usesLocalCoords()) { | 106 if (child->usesLocalCoords()) { |
| 110 fUsesLocalCoords = true; | 107 fUsesLocalCoords = true; |
| 111 } | 108 } |
| 112 | 109 |
| 110 int index = fChildProcessors.count(); |
| 111 fChildProcessors.push_back(child.release()); |
| 112 |
| 113 return index; | 113 return index; |
| 114 } | 114 } |
| 115 | 115 |
| 116 void GrFragmentProcessor::notifyRefCntIsZero() const { | 116 void GrFragmentProcessor::notifyRefCntIsZero() const { |
| 117 // See comment above GrProgramElement for a detailed explanation of why we d
o this. | 117 // See comment above GrProgramElement for a detailed explanation of why we d
o this. |
| 118 for (int i = 0; i < fChildProcessors.count(); ++i) { | 118 for (int i = 0; i < fChildProcessors.count(); ++i) { |
| 119 fChildProcessors[i]->addPendingExecution(); | 119 fChildProcessors[i]->addPendingExecution(); |
| 120 fChildProcessors[i]->unref(); | 120 fChildProcessors[i]->unref(); |
| 121 } | 121 } |
| 122 } | 122 } |
| 123 | 123 |
| 124 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) con
st { | 124 bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) con
st { |
| 125 if (this->numTransforms() != that.numTransforms()) { | 125 if (this->numTransforms() != that.numTransforms()) { |
| 126 return false; | 126 return false; |
| 127 } | 127 } |
| 128 int count = this->numTransforms(); | 128 int count = this->numTransforms(); |
| 129 for (int i = 0; i < count; ++i) { | 129 for (int i = 0; i < count; ++i) { |
| 130 if (this->coordTransform(i) != that.coordTransform(i)) { | 130 if (this->coordTransform(i) != that.coordTransform(i)) { |
| 131 return false; | 131 return false; |
| 132 } | 132 } |
| 133 } | 133 } |
| 134 return true; | 134 return true; |
| 135 } | 135 } |
| 136 | 136 |
| 137 const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputAlpha( | 137 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputAlpha( |
| 138 const GrFragmentProcessor* fp) { | 138 sk_sp<GrFragmentProcessor> fp) { |
| 139 if (!fp) { | 139 if (!fp) { |
| 140 return nullptr; | 140 return nullptr; |
| 141 } | 141 } |
| 142 return GrXfermodeFragmentProcessor::CreateFromDstProcessor(fp, SkXfermode::k
DstIn_Mode); | 142 return GrXfermodeFragmentProcessor::MakeFromDstProcessor(std::move(fp), |
| 143 SkXfermode::kDstIn_
Mode); |
| 143 } | 144 } |
| 144 | 145 |
| 145 const GrFragmentProcessor* GrFragmentProcessor::MulOutputByInputUnpremulColor( | 146 sk_sp<GrFragmentProcessor> GrFragmentProcessor::MulOutputByInputUnpremulColor( |
| 146 const GrFragmentProcessor* fp) { | 147 sk_sp<GrFragmentProcessor> fp) { |
| 147 | 148 |
| 148 class PremulFragmentProcessor : public GrFragmentProcessor { | 149 class PremulFragmentProcessor : public GrFragmentProcessor { |
| 149 public: | 150 public: |
| 150 PremulFragmentProcessor(const GrFragmentProcessor* processor) { | 151 PremulFragmentProcessor(sk_sp<GrFragmentProcessor> processor) { |
| 151 this->initClassID<PremulFragmentProcessor>(); | 152 this->initClassID<PremulFragmentProcessor>(); |
| 152 this->registerChildProcessor(processor); | 153 this->registerChildProcessor(processor); |
| 153 } | 154 } |
| 154 | 155 |
| 155 const char* name() const override { return "Premultiply"; } | 156 const char* name() const override { return "Premultiply"; } |
| 156 | 157 |
| 157 private: | 158 private: |
| 158 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { | 159 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { |
| 159 class GLFP : public GrGLSLFragmentProcessor { | 160 class GLFP : public GrGLSLFragmentProcessor { |
| 160 public: | 161 public: |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 if (commonFlags & kB_GrColorComponentFlag) { | 203 if (commonFlags & kB_GrColorComponentFlag) { |
| 203 color |= SkMulDiv255Round(GrColorUnpackB(c0), GrColorUnpackB(c1)
) << | 204 color |= SkMulDiv255Round(GrColorUnpackB(c0), GrColorUnpackB(c1)
) << |
| 204 GrColor_SHIFT_B; | 205 GrColor_SHIFT_B; |
| 205 } | 206 } |
| 206 inout->setToOther(commonFlags, color, GrInvariantOutput::kWill_ReadI
nput); | 207 inout->setToOther(commonFlags, color, GrInvariantOutput::kWill_ReadI
nput); |
| 207 } | 208 } |
| 208 }; | 209 }; |
| 209 if (!fp) { | 210 if (!fp) { |
| 210 return nullptr; | 211 return nullptr; |
| 211 } | 212 } |
| 212 return new PremulFragmentProcessor(fp); | 213 return sk_sp<GrFragmentProcessor>(new PremulFragmentProcessor(std::move(fp))
); |
| 213 } | 214 } |
| 214 | 215 |
| 215 ////////////////////////////////////////////////////////////////////////////// | 216 ////////////////////////////////////////////////////////////////////////////// |
| 216 | 217 |
| 217 const GrFragmentProcessor* GrFragmentProcessor::OverrideInput(const GrFragmentPr
ocessor* fp, | 218 sk_sp<GrFragmentProcessor> GrFragmentProcessor::OverrideInput(sk_sp<GrFragmentPr
ocessor> fp, |
| 218 GrColor color) { | 219 GrColor color) { |
| 219 class ReplaceInputFragmentProcessor : public GrFragmentProcessor { | 220 class ReplaceInputFragmentProcessor : public GrFragmentProcessor { |
| 220 public: | 221 public: |
| 221 ReplaceInputFragmentProcessor(const GrFragmentProcessor* child, GrColor
color) | 222 ReplaceInputFragmentProcessor(sk_sp<GrFragmentProcessor> child, GrColor
color) |
| 222 : fColor(color) { | 223 : fColor(color) { |
| 223 this->initClassID<ReplaceInputFragmentProcessor>(); | 224 this->initClassID<ReplaceInputFragmentProcessor>(); |
| 224 this->registerChildProcessor(child); | 225 this->registerChildProcessor(std::move(child)); |
| 225 } | 226 } |
| 226 | 227 |
| 227 const char* name() const override { return "Replace Color"; } | 228 const char* name() const override { return "Replace Color"; } |
| 228 | 229 |
| 229 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { | 230 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { |
| 230 class GLFP : public GrGLSLFragmentProcessor { | 231 class GLFP : public GrGLSLFragmentProcessor { |
| 231 public: | 232 public: |
| 232 GLFP() : fHaveSetColor(false) {} | 233 GLFP() : fHaveSetColor(false) {} |
| 233 void emitCode(EmitArgs& args) override { | 234 void emitCode(EmitArgs& args) override { |
| 234 const char* colorName; | 235 const char* colorName; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 GrInvariantOutput::kWillNot_ReadInput); | 279 GrInvariantOutput::kWillNot_ReadInput); |
| 279 this->childProcessor(0).computeInvariantOutput(inout); | 280 this->childProcessor(0).computeInvariantOutput(inout); |
| 280 } | 281 } |
| 281 | 282 |
| 282 GrColor fColor; | 283 GrColor fColor; |
| 283 }; | 284 }; |
| 284 | 285 |
| 285 GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags, false); | 286 GrInvariantOutput childOut(0x0, kNone_GrColorComponentFlags, false); |
| 286 fp->computeInvariantOutput(&childOut); | 287 fp->computeInvariantOutput(&childOut); |
| 287 if (childOut.willUseInputColor()) { | 288 if (childOut.willUseInputColor()) { |
| 288 return new ReplaceInputFragmentProcessor(fp, color); | 289 return sk_sp<GrFragmentProcessor>(new ReplaceInputFragmentProcessor(std:
:move(fp), color)); |
| 289 } else { | 290 } else { |
| 290 return SkRef(fp); | 291 return fp; |
| 291 } | 292 } |
| 292 } | 293 } |
| 293 | 294 |
| 294 const GrFragmentProcessor* GrFragmentProcessor::RunInSeries(const GrFragmentProc
essor* series[], | 295 sk_sp<GrFragmentProcessor> GrFragmentProcessor::RunInSeries(sk_sp<GrFragmentProc
essor>* series, |
| 295 int cnt) { | 296 int cnt) { |
| 296 class SeriesFragmentProcessor : public GrFragmentProcessor { | 297 class SeriesFragmentProcessor : public GrFragmentProcessor { |
| 297 public: | 298 public: |
| 298 SeriesFragmentProcessor(const GrFragmentProcessor* children[], int cnt){ | 299 SeriesFragmentProcessor(sk_sp<GrFragmentProcessor>* children, int cnt){ |
| 299 SkASSERT(cnt > 1); | 300 SkASSERT(cnt > 1); |
| 300 this->initClassID<SeriesFragmentProcessor>(); | 301 this->initClassID<SeriesFragmentProcessor>(); |
| 301 for (int i = 0; i < cnt; ++i) { | 302 for (int i = 0; i < cnt; ++i) { |
| 302 this->registerChildProcessor(children[i]); | 303 this->registerChildProcessor(std::move(children[i])); |
| 303 } | 304 } |
| 304 } | 305 } |
| 305 | 306 |
| 306 const char* name() const override { return "Series"; } | 307 const char* name() const override { return "Series"; } |
| 307 | 308 |
| 308 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { | 309 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { |
| 309 class GLFP : public GrGLSLFragmentProcessor { | 310 class GLFP : public GrGLSLFragmentProcessor { |
| 310 public: | 311 public: |
| 311 void emitCode(EmitArgs& args) override { | 312 void emitCode(EmitArgs& args) override { |
| 312 SkString input(args.fInputColor); | 313 SkString input(args.fInputColor); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 323 return new GLFP; | 324 return new GLFP; |
| 324 } | 325 } |
| 325 | 326 |
| 326 private: | 327 private: |
| 327 void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) co
nst override {} | 328 void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) co
nst override {} |
| 328 | 329 |
| 329 bool onIsEqual(const GrFragmentProcessor&) const override { return true;
} | 330 bool onIsEqual(const GrFragmentProcessor&) const override { return true;
} |
| 330 | 331 |
| 331 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { | 332 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { |
| 332 GrProcOptInfo info; | 333 GrProcOptInfo info; |
| 333 SkTDArray<const GrFragmentProcessor*> children; | 334 info.calcWithInitialValues(fChildProcessors.begin(), fChildProcessor
s.count(), |
| 334 children.setCount(this->numChildProcessors()); | 335 inout->color(), inout->validFlags(), fals
e, false); |
| 335 for (int i = 0; i < children.count(); ++i) { | |
| 336 children[i] = &this->childProcessor(i); | |
| 337 } | |
| 338 info.calcWithInitialValues(children.begin(), children.count(), inout
->color(), | |
| 339 inout->validFlags(), false, false); | |
| 340 for (int i = 0; i < this->numChildProcessors(); ++i) { | 336 for (int i = 0; i < this->numChildProcessors(); ++i) { |
| 341 this->childProcessor(i).computeInvariantOutput(inout); | 337 this->childProcessor(i).computeInvariantOutput(inout); |
| 342 } | 338 } |
| 343 } | 339 } |
| 344 }; | 340 }; |
| 345 | 341 |
| 346 if (!cnt) { | 342 if (!cnt) { |
| 347 return nullptr; | 343 return nullptr; |
| 348 } | 344 } |
| 349 | 345 |
| 350 // Run the through the series, do the invariant output processing, and look
for eliminations. | 346 // Run the through the series, do the invariant output processing, and look
for eliminations. |
| 351 SkTDArray<const GrFragmentProcessor*> replacementSeries; | |
| 352 SkAutoTUnref<const GrFragmentProcessor> colorFP; | |
| 353 GrProcOptInfo info; | 347 GrProcOptInfo info; |
| 348 info.calcWithInitialValues(sk_sp_address_as_pointer_address(series), cnt, |
| 349 0x0, kNone_GrColorComponentFlags, false, false); |
| 350 if (kRGBA_GrColorComponentFlags == info.validFlags()) { |
| 351 return GrConstColorProcessor::Make(info.color(), GrConstColorProcessor::
kIgnore_InputMode); |
| 352 } |
| 354 | 353 |
| 355 info.calcWithInitialValues(series, cnt, 0x0, kNone_GrColorComponentFlags, fa
lse, false); | 354 SkTArray<sk_sp<GrFragmentProcessor>> replacementSeries; |
| 356 if (kRGBA_GrColorComponentFlags == info.validFlags()) { | 355 |
| 357 return GrConstColorProcessor::Create(info.color(), | 356 int firstIdx = info.firstEffectiveProcessorIndex(); |
| 358 GrConstColorProcessor::kIgnore_Inpu
tMode); | 357 cnt -= firstIdx; |
| 358 if (firstIdx > 0 && info.inputColorIsUsed()) { |
| 359 sk_sp<GrFragmentProcessor> colorFP(GrConstColorProcessor::Make( |
| 360 info.inputColorToFirstEffectiveProccesor(), GrConstColorProcessor::k
Ignore_InputMode)); |
| 361 cnt += 1; |
| 362 replacementSeries.reserve(cnt); |
| 363 replacementSeries.emplace_back(std::move(colorFP)); |
| 364 for (int i = 0; i < cnt - 1; ++i) { |
| 365 replacementSeries.emplace_back(std::move(series[firstIdx + i])); |
| 366 } |
| 367 series = replacementSeries.begin(); |
| 359 } else { | 368 } else { |
| 360 int firstIdx = info.firstEffectiveProcessorIndex(); | 369 series += firstIdx; |
| 361 cnt -= firstIdx; | 370 cnt -= firstIdx; |
| 362 if (firstIdx > 0 && info.inputColorIsUsed()) { | |
| 363 colorFP.reset(GrConstColorProcessor::Create(info.inputColorToFirstEf
fectiveProccesor(), | |
| 364 GrConstColorProcessor::k
Ignore_InputMode)); | |
| 365 cnt += 1; | |
| 366 replacementSeries.setCount(cnt); | |
| 367 replacementSeries[0] = colorFP; | |
| 368 for (int i = 0; i < cnt - 1; ++i) { | |
| 369 replacementSeries[i + 1] = series[firstIdx + i]; | |
| 370 } | |
| 371 series = replacementSeries.begin(); | |
| 372 } else { | |
| 373 series += firstIdx; | |
| 374 cnt -= firstIdx; | |
| 375 } | |
| 376 } | 371 } |
| 377 | 372 |
| 378 if (1 == cnt) { | 373 if (1 == cnt) { |
| 379 return SkRef(series[0]); | 374 return series[0]; |
| 380 } else { | |
| 381 return new SeriesFragmentProcessor(series, cnt); | |
| 382 } | 375 } |
| 376 return sk_sp<GrFragmentProcessor>(new SeriesFragmentProcessor(series, cnt)); |
| 383 } | 377 } |
| OLD | NEW |