blob: bd78dc927e3959d0f1bbd0df108b45b7ba3386f7 [file] [log] [blame]
/*
* 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 "GrFragmentProcessor.h"
#include "GrPaint.h"
#include "GrPipelineInput.h"
#include "SkTemplates.h"
class GrAppliedClip;
class GrXPFactory;
class GrProcessorSet : private SkNoncopyable {
public:
GrProcessorSet(GrPaint&& paint);
~GrProcessorSet() {
// We are deliberately not using sk_sp here because this will be updated to work with
// "pending execution" refs.
for (auto fp : fFragmentProcessors) {
fp->unref();
}
}
int numColorFragmentProcessors() const { return fColorFragmentProcessorCnt; }
int numCoverageFragmentProcessors() const {
return fFragmentProcessors.count() - fColorFragmentProcessorCnt;
}
int numFragmentProcessors() const { return fFragmentProcessors.count(); }
const GrFragmentProcessor* colorFragmentProcessor(int idx) const {
SkASSERT(idx < fColorFragmentProcessorCnt);
return fFragmentProcessors[idx];
}
const GrFragmentProcessor* coverageFragmentProcessor(int idx) const {
return fFragmentProcessors[idx + fColorFragmentProcessorCnt];
}
const GrXPFactory* xpFactory() const { return fXPFactory; }
bool usesDistanceVectorField() const { return SkToBool(fFlags & kUseDistanceVectorField_Flag); }
bool disableOutputConversionToSRGB() const {
return SkToBool(fFlags & kDisableOutputConversionToSRGB_Flag);
}
bool allowSRGBInputs() const { return SkToBool(fFlags & kAllowSRGBInputs_Flag); }
/**
* This is used to track analysis of color and coverage values through the fragment processors.
*/
class FragmentProcessorAnalysis {
public:
FragmentProcessorAnalysis() = default;
// This version is used by a unit test that assumes no clip, no processors, and no PLS.
FragmentProcessorAnalysis(const GrPipelineInput& colorInput,
const GrPipelineInput coverageInput, const GrCaps&);
void reset(const GrPipelineInput& colorInput, const GrPipelineInput coverageInput,
const GrProcessorSet&, bool usesPLSDstRead, const GrAppliedClip&, const GrCaps&);
int initialColorProcessorsToEliminate(GrColor* newInputColor) const {
if (fInitialColorProcessorsToEliminate > 0) {
*newInputColor = fOverrideInputColor;
}
return fInitialColorProcessorsToEliminate;
}
bool usesPLSDstRead() const { return fUsesPLSDstRead; }
bool isCompatibleWithCoverageAsAlpha() const { return fCompatibleWithCoverageAsAlpha; }
bool isOutputColorOpaque() const {
return ColorType::kOpaque == fColorType || ColorType::kOpaqueConstant == fColorType;
}
bool hasKnownOutputColor(GrColor* color = nullptr) const {
bool constant =
ColorType::kConstant == fColorType || ColorType::kOpaqueConstant == fColorType;
if (constant && color) {
*color = fKnownOutputColor;
}
return constant;
}
bool hasCoverage() const { return CoverageType::kNone != fCoverageType; }
bool hasLCDCoverage() const { return CoverageType::kLCD == fCoverageType; }
private:
void internalReset(const GrPipelineInput& colorInput, const GrPipelineInput coverageInput,
const GrProcessorSet&, bool usesPLSDstRead,
const GrFragmentProcessor* clipFP, const GrCaps&);
enum class ColorType { kUnknown, kOpaqueConstant, kConstant, kOpaque };
enum class CoverageType { kNone, kSingleChannel, kLCD };
bool fUsesPLSDstRead = false;
bool fCompatibleWithCoverageAsAlpha = true;
CoverageType fCoverageType = CoverageType::kNone;
ColorType fColorType = ColorType::kUnknown;
int fInitialColorProcessorsToEliminate = 0;
GrColor fOverrideInputColor;
GrColor fKnownOutputColor;
};
private:
const GrXPFactory* fXPFactory = nullptr;
SkAutoSTArray<4, const GrFragmentProcessor*> fFragmentProcessors;
int fColorFragmentProcessorCnt;
enum Flags : uint32_t {
kUseDistanceVectorField_Flag = 0x1,
kDisableOutputConversionToSRGB_Flag = 0x2,
kAllowSRGBInputs_Flag = 0x4
};
uint32_t fFlags;
};
#endif