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