123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- /*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "src/core/SkBlendModePriv.h"
- #include "src/gpu/GrAppliedClip.h"
- #include "src/gpu/GrCaps.h"
- #include "src/gpu/GrProcessorSet.h"
- #include "src/gpu/GrUserStencilSettings.h"
- #include "src/gpu/GrXferProcessor.h"
- #include "src/gpu/effects/GrPorterDuffXferProcessor.h"
- const GrProcessorSet& GrProcessorSet::EmptySet() {
- static GrProcessorSet gEmpty(GrProcessorSet::Empty::kEmpty);
- return gEmpty;
- }
- GrProcessorSet GrProcessorSet::MakeEmptySet() {
- return GrProcessorSet(GrProcessorSet::Empty::kEmpty);
- }
- GrProcessorSet::GrProcessorSet(GrPaint&& paint) : fXP(paint.getXPFactory()) {
- fFlags = 0;
- if (paint.numColorFragmentProcessors() <= kMaxColorProcessors) {
- fColorFragmentProcessorCnt = paint.numColorFragmentProcessors();
- fFragmentProcessors.reset(paint.numTotalFragmentProcessors());
- int i = 0;
- for (auto& fp : paint.fColorFragmentProcessors) {
- SkASSERT(fp.get());
- fFragmentProcessors[i++] = std::move(fp);
- }
- for (auto& fp : paint.fCoverageFragmentProcessors) {
- SkASSERT(fp.get());
- fFragmentProcessors[i++] = std::move(fp);
- }
- } else {
- SkDebugf("Insane number of color fragment processors in paint. Dropping all processors.");
- fColorFragmentProcessorCnt = 0;
- }
- SkDEBUGCODE(paint.fAlive = false;)
- }
- GrProcessorSet::GrProcessorSet(SkBlendMode mode)
- : fXP(SkBlendMode_AsXPFactory(mode))
- , fColorFragmentProcessorCnt(0)
- , fFragmentProcessorOffset(0)
- , fFlags(0) {}
- GrProcessorSet::GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP)
- : fFragmentProcessors(1)
- , fXP((const GrXPFactory*)nullptr)
- , fColorFragmentProcessorCnt(1)
- , fFragmentProcessorOffset(0)
- , fFlags(0) {
- SkASSERT(colorFP);
- fFragmentProcessors[0] = std::move(colorFP);
- }
- GrProcessorSet::GrProcessorSet(GrProcessorSet&& that)
- : fXP(std::move(that.fXP))
- , fColorFragmentProcessorCnt(that.fColorFragmentProcessorCnt)
- , fFragmentProcessorOffset(0)
- , fFlags(that.fFlags) {
- fFragmentProcessors.reset(that.fFragmentProcessors.count() - that.fFragmentProcessorOffset);
- for (int i = 0; i < fFragmentProcessors.count(); ++i) {
- fFragmentProcessors[i] =
- std::move(that.fFragmentProcessors[i + that.fFragmentProcessorOffset]);
- }
- that.fColorFragmentProcessorCnt = 0;
- that.fFragmentProcessors.reset(0);
- }
- GrProcessorSet::~GrProcessorSet() {
- if (this->isFinalized() && this->xferProcessor()) {
- this->xferProcessor()->unref();
- }
- }
- #ifdef SK_DEBUG
- SkString dump_fragment_processor_tree(const GrFragmentProcessor* fp, int indentCnt) {
- SkString result;
- SkString indentString;
- for (int i = 0; i < indentCnt; ++i) {
- indentString.append(" ");
- }
- result.appendf("%s%s %s \n", indentString.c_str(), fp->name(), fp->dumpInfo().c_str());
- if (fp->numChildProcessors()) {
- for (int i = 0; i < fp->numChildProcessors(); ++i) {
- result += dump_fragment_processor_tree(&fp->childProcessor(i), indentCnt + 1);
- }
- }
- return result;
- }
- SkString GrProcessorSet::dumpProcessors() const {
- SkString result;
- if (this->numFragmentProcessors()) {
- if (this->numColorFragmentProcessors()) {
- result.append("Color Fragment Processors:\n");
- for (int i = 0; i < this->numColorFragmentProcessors(); ++i) {
- result += dump_fragment_processor_tree(this->colorFragmentProcessor(i), 1);
- }
- } else {
- result.append("No color fragment processors.\n");
- }
- if (this->numCoverageFragmentProcessors()) {
- result.append("Coverage Fragment Processors:\n");
- for (int i = 0; i < this->numColorFragmentProcessors(); ++i) {
- result += dump_fragment_processor_tree(this->coverageFragmentProcessor(i), 1);
- }
- } else {
- result.append("No coverage fragment processors.\n");
- }
- } else {
- result.append("No color or coverage fragment processors.\n");
- }
- if (this->isFinalized()) {
- result.append("Xfer Processor: ");
- if (this->xferProcessor()) {
- result.appendf("%s\n", this->xferProcessor()->name());
- } else {
- result.append("SrcOver\n");
- }
- } else {
- result.append("XP Factory dumping not implemented.\n");
- }
- return result;
- }
- #endif
- bool GrProcessorSet::operator==(const GrProcessorSet& that) const {
- SkASSERT(this->isFinalized());
- SkASSERT(that.isFinalized());
- int fpCount = this->numFragmentProcessors();
- if (((fFlags ^ that.fFlags) & ~kFinalized_Flag) || fpCount != that.numFragmentProcessors() ||
- fColorFragmentProcessorCnt != that.fColorFragmentProcessorCnt) {
- return false;
- }
- for (int i = 0; i < fpCount; ++i) {
- int a = i + fFragmentProcessorOffset;
- int b = i + that.fFragmentProcessorOffset;
- if (!fFragmentProcessors[a]->isEqual(*that.fFragmentProcessors[b])) {
- return false;
- }
- }
- // Most of the time both of these are null
- if (!this->xferProcessor() && !that.xferProcessor()) {
- return true;
- }
- const GrXferProcessor& thisXP = this->xferProcessor()
- ? *this->xferProcessor()
- : GrPorterDuffXPFactory::SimpleSrcOverXP();
- const GrXferProcessor& thatXP = that.xferProcessor()
- ? *that.xferProcessor()
- : GrPorterDuffXPFactory::SimpleSrcOverXP();
- return thisXP.isEqual(thatXP);
- }
- GrProcessorSet::Analysis GrProcessorSet::finalize(
- const GrProcessorAnalysisColor& colorInput, const GrProcessorAnalysisCoverage coverageInput,
- const GrAppliedClip* clip, const GrUserStencilSettings* userStencil,
- bool hasMixedSampledCoverage, const GrCaps& caps, GrClampType clampType,
- SkPMColor4f* overrideInputColor) {
- SkASSERT(!this->isFinalized());
- SkASSERT(!fFragmentProcessorOffset);
- GrProcessorSet::Analysis analysis;
- analysis.fCompatibleWithCoverageAsAlpha = GrProcessorAnalysisCoverage::kLCD != coverageInput;
- const std::unique_ptr<const GrFragmentProcessor>* fps =
- fFragmentProcessors.get() + fFragmentProcessorOffset;
- GrColorFragmentProcessorAnalysis colorAnalysis(
- colorInput, unique_ptr_address_as_pointer_address(fps), fColorFragmentProcessorCnt);
- fps += fColorFragmentProcessorCnt;
- int n = this->numCoverageFragmentProcessors();
- bool hasCoverageFP = n > 0;
- bool coverageUsesLocalCoords = false;
- for (int i = 0; i < n; ++i) {
- if (!fps[i]->compatibleWithCoverageAsAlpha()) {
- analysis.fCompatibleWithCoverageAsAlpha = false;
- }
- coverageUsesLocalCoords |= fps[i]->usesLocalCoords();
- }
- if (clip) {
- hasCoverageFP = hasCoverageFP || clip->numClipCoverageFragmentProcessors();
- for (int i = 0; i < clip->numClipCoverageFragmentProcessors(); ++i) {
- const GrFragmentProcessor* clipFP = clip->clipCoverageFragmentProcessor(i);
- analysis.fCompatibleWithCoverageAsAlpha &= clipFP->compatibleWithCoverageAsAlpha();
- coverageUsesLocalCoords |= clipFP->usesLocalCoords();
- }
- }
- int colorFPsToEliminate = colorAnalysis.initialProcessorsToEliminate(overrideInputColor);
- analysis.fInputColorType = static_cast<Analysis::PackedInputColorType>(
- colorFPsToEliminate ? Analysis::kOverridden_InputColorType
- : Analysis::kOriginal_InputColorType);
- GrProcessorAnalysisCoverage outputCoverage;
- if (GrProcessorAnalysisCoverage::kLCD == coverageInput) {
- outputCoverage = GrProcessorAnalysisCoverage::kLCD;
- } else if (hasCoverageFP || GrProcessorAnalysisCoverage::kSingleChannel == coverageInput) {
- outputCoverage = GrProcessorAnalysisCoverage::kSingleChannel;
- } else {
- outputCoverage = GrProcessorAnalysisCoverage::kNone;
- }
- GrXPFactory::AnalysisProperties props = GrXPFactory::GetAnalysisProperties(
- this->xpFactory(), colorAnalysis.outputColor(), outputCoverage, caps, clampType);
- if (!this->numCoverageFragmentProcessors() &&
- GrProcessorAnalysisCoverage::kNone == coverageInput) {
- }
- analysis.fRequiresDstTexture =
- SkToBool(props & GrXPFactory::AnalysisProperties::kRequiresDstTexture);
- analysis.fCompatibleWithCoverageAsAlpha &=
- SkToBool(props & GrXPFactory::AnalysisProperties::kCompatibleWithCoverageAsAlpha);
- analysis.fRequiresNonOverlappingDraws = SkToBool(
- props & GrXPFactory::AnalysisProperties::kRequiresNonOverlappingDraws);
- if (props & GrXPFactory::AnalysisProperties::kIgnoresInputColor) {
- colorFPsToEliminate = this->numColorFragmentProcessors();
- analysis.fInputColorType =
- static_cast<Analysis::PackedInputColorType>(Analysis::kIgnored_InputColorType);
- analysis.fUsesLocalCoords = coverageUsesLocalCoords;
- } else {
- analysis.fCompatibleWithCoverageAsAlpha &=
- colorAnalysis.allProcessorsCompatibleWithCoverageAsAlpha();
- analysis.fUsesLocalCoords = coverageUsesLocalCoords | colorAnalysis.usesLocalCoords();
- }
- for (int i = 0; i < colorFPsToEliminate; ++i) {
- fFragmentProcessors[i].reset(nullptr);
- }
- fFragmentProcessorOffset = colorFPsToEliminate;
- fColorFragmentProcessorCnt -= colorFPsToEliminate;
- analysis.fHasColorFragmentProcessor = (fColorFragmentProcessorCnt != 0);
- auto xp = GrXPFactory::MakeXferProcessor(this->xpFactory(), colorAnalysis.outputColor(),
- outputCoverage, hasMixedSampledCoverage, caps,
- clampType);
- fXP.fProcessor = xp.release();
- fFlags |= kFinalized_Flag;
- analysis.fIsInitialized = true;
- #ifdef SK_DEBUG
- bool hasXferBarrier =
- fXP.fProcessor &&
- GrXferBarrierType::kNone_GrXferBarrierType != fXP.fProcessor->xferBarrierType(caps);
- bool needsNonOverlappingDraws = analysis.fRequiresDstTexture || hasXferBarrier;
- SkASSERT(analysis.fRequiresNonOverlappingDraws == needsNonOverlappingDraws);
- #endif
- return analysis;
- }
|