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 |