123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /*
- * Copyright 2017 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef GrProcessorSet_DEFINED
- #define GrProcessorSet_DEFINED
- #include "include/private/SkTemplates.h"
- #include "src/gpu/GrFragmentProcessor.h"
- #include "src/gpu/GrPaint.h"
- #include "src/gpu/GrProcessorAnalysis.h"
- #include "src/gpu/GrXferProcessor.h"
- struct GrUserStencilSettings;
- class GrAppliedClip;
- class GrXPFactory;
- class GrProcessorSet {
- private:
- // Arbitrary constructor arg for empty set and analysis
- enum class Empty { kEmpty };
- public:
- GrProcessorSet(GrPaint&&);
- GrProcessorSet(SkBlendMode);
- GrProcessorSet(std::unique_ptr<GrFragmentProcessor> colorFP);
- GrProcessorSet(GrProcessorSet&&);
- GrProcessorSet(const GrProcessorSet&) = delete;
- GrProcessorSet& operator=(const GrProcessorSet&) = delete;
- ~GrProcessorSet();
- int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
- int numCoverageFragmentProcessors() const {
- return this->numFragmentProcessors() - fColorFragmentProcessorCnt;
- }
- const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
- SkASSERT(idx < fColorFragmentProcessorCnt);
- return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
- }
- const GrFragmentProcessor* coverageFragmentProcessor(int idx) const {
- return fFragmentProcessors[idx + fColorFragmentProcessorCnt +
- fFragmentProcessorOffset].get();
- }
- const GrXferProcessor* xferProcessor() const {
- SkASSERT(this->isFinalized());
- return fXP.fProcessor;
- }
- sk_sp<const GrXferProcessor> refXferProcessor() const {
- SkASSERT(this->isFinalized());
- return sk_ref_sp(fXP.fProcessor);
- }
- std::unique_ptr<const GrFragmentProcessor> detachColorFragmentProcessor(int idx) {
- SkASSERT(idx < fColorFragmentProcessorCnt);
- return std::move(fFragmentProcessors[idx + fFragmentProcessorOffset]);
- }
- std::unique_ptr<const GrFragmentProcessor> detachCoverageFragmentProcessor(int idx) {
- return std::move(
- fFragmentProcessors[idx + fFragmentProcessorOffset + fColorFragmentProcessorCnt]);
- }
- /** Comparisons are only legal on finalized processor sets. */
- bool operator==(const GrProcessorSet& that) const;
- bool operator!=(const GrProcessorSet& that) const { return !(*this == that); }
- /**
- * This is used to report results of processor analysis when a processor set is finalized (see
- * below).
- */
- class Analysis {
- public:
- Analysis(const Analysis&) = default;
- Analysis() { *reinterpret_cast<uint32_t*>(this) = 0; }
- bool isInitialized() const { return fIsInitialized; }
- bool usesLocalCoords() const { return fUsesLocalCoords; }
- bool requiresDstTexture() const { return fRequiresDstTexture; }
- bool requiresNonOverlappingDraws() const { return fRequiresNonOverlappingDraws; }
- bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
- // Indicates whether all color fragment processors were eliminated in the analysis.
- bool hasColorFragmentProcessor() const { return fHasColorFragmentProcessor; }
- bool inputColorIsIgnored() const { return fInputColorType == kIgnored_InputColorType; }
- bool inputColorIsOverridden() const {
- return fInputColorType == kOverridden_InputColorType;
- }
- private:
- constexpr Analysis(Empty)
- : fUsesLocalCoords(false)
- , fCompatibleWithCoverageAsAlpha(true)
- , fRequiresDstTexture(false)
- , fRequiresNonOverlappingDraws(false)
- , fHasColorFragmentProcessor(false)
- , fIsInitialized(true)
- , fInputColorType(kOriginal_InputColorType) {}
- enum InputColorType : uint32_t {
- kOriginal_InputColorType,
- kOverridden_InputColorType,
- kIgnored_InputColorType
- };
- // MSVS 2015 won't pack different underlying types
- using PackedBool = uint32_t;
- using PackedInputColorType = uint32_t;
- PackedBool fUsesLocalCoords : 1;
- PackedBool fCompatibleWithCoverageAsAlpha : 1;
- PackedBool fRequiresDstTexture : 1;
- PackedBool fRequiresNonOverlappingDraws : 1;
- PackedBool fHasColorFragmentProcessor : 1;
- PackedBool fIsInitialized : 1;
- PackedInputColorType fInputColorType : 2;
- friend class GrProcessorSet;
- };
- GR_STATIC_ASSERT(sizeof(Analysis) <= sizeof(uint32_t));
- /**
- * This analyzes the processors given an op's input color and coverage as well as a clip. The
- * state of the processor set may change to an equivalent but more optimal set of processors.
- * This new state requires that the caller respect the returned 'inputColorOverride'. This is
- * indicated by the returned Analysis's inputColorIsOverridden(). 'inputColorOverride' will not
- * be written if the analysis does not override the input color.
- *
- * This must be called before the processor set is used to construct a GrPipeline and may only
- * be called once.
- *
- * This also puts the processors in "pending execution" state and must be called when an op
- * that owns a processor set is recorded to ensure pending and writes are propagated to
- * resources referred to by the processors. Otherwise, data hazards may occur.
- */
- Analysis finalize(
- const GrProcessorAnalysisColor&, const GrProcessorAnalysisCoverage,
- const GrAppliedClip*, const GrUserStencilSettings*, bool hasMixedSampledCoverage,
- const GrCaps&, GrClampType, SkPMColor4f* inputColorOverride);
- bool isFinalized() const { return SkToBool(kFinalized_Flag & fFlags); }
- /** These are valid only for non-LCD coverage. */
- static const GrProcessorSet& EmptySet();
- static GrProcessorSet MakeEmptySet();
- static constexpr const Analysis EmptySetAnalysis() { return Analysis(Empty::kEmpty); }
- #ifdef SK_DEBUG
- SkString dumpProcessors() const;
- #endif
- void visitProxies(const GrOp::VisitProxyFunc& func) const {
- for (int i = 0; i < this->numFragmentProcessors(); ++i) {
- GrFragmentProcessor::TextureAccessIter iter(this->fragmentProcessor(i));
- while (const GrFragmentProcessor::TextureSampler* sampler = iter.next()) {
- bool mipped = (GrSamplerState::Filter::kMipMap == sampler->samplerState().filter());
- func(sampler->proxy(), GrMipMapped(mipped));
- }
- }
- }
- private:
- GrProcessorSet(Empty) : fXP((const GrXferProcessor*)nullptr), fFlags(kFinalized_Flag) {}
- int numFragmentProcessors() const {
- return fFragmentProcessors.count() - fFragmentProcessorOffset;
- }
- const GrFragmentProcessor* fragmentProcessor(int idx) const {
- return fFragmentProcessors[idx + fFragmentProcessorOffset].get();
- }
- // This absurdly large limit allows Analysis and this to pack fields together.
- static constexpr int kMaxColorProcessors = UINT8_MAX;
- enum Flags : uint16_t { kFinalized_Flag = 0x1 };
- union XP {
- XP(const GrXPFactory* factory) : fFactory(factory) {}
- XP(const GrXferProcessor* processor) : fProcessor(processor) {}
- explicit XP(XP&& that) : fProcessor(that.fProcessor) {
- SkASSERT(fProcessor == that.fProcessor);
- that.fProcessor = nullptr;
- }
- const GrXPFactory* fFactory;
- const GrXferProcessor* fProcessor;
- };
- const GrXPFactory* xpFactory() const {
- SkASSERT(!this->isFinalized());
- return fXP.fFactory;
- }
- SkAutoSTArray<4, std::unique_ptr<const GrFragmentProcessor>> fFragmentProcessors;
- XP fXP;
- uint8_t fColorFragmentProcessorCnt = 0;
- uint8_t fFragmentProcessorOffset = 0;
- uint8_t fFlags;
- };
- #endif
|