1 /* 2 * Copyright 2022 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef skgpu_graphite_PrecompileInternal_DEFINED 9 #define skgpu_graphite_PrecompileInternal_DEFINED 10 11 #include "include/core/SkBlendMode.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/gpu/graphite/precompile/PaintOptions.h" 14 #include "include/gpu/graphite/precompile/PrecompileBase.h" 15 #include "include/private/base/SkTArray.h" 16 #include "include/private/base/SkTemplates.h" 17 #include "src/gpu/graphite/precompile/PaintOptionsPriv.h" 18 19 #include <functional> 20 #include <optional> 21 #include <vector> 22 23 class SkRuntimeEffect; 24 25 namespace skgpu::graphite { 26 27 enum class Coverage; 28 class Context; 29 30 31 class UniquePaintParamsID; 32 33 // Create the Pipelines specified by 'options' by combining the shading portion w/ the specified 34 // 'drawTypes' and a stock set of RenderPass descriptors (e.g., kDepth+msaa, kDepthStencil+msaa) 35 void PrecompileCombinations(Context* context, 36 const PaintOptions& options, 37 const KeyContext& keyContext, 38 DrawTypeFlags drawTypes, 39 bool withPrimitiveBlender, 40 Coverage coverage); 41 42 //-------------------------------------------------------------------------------------------------- 43 44 class PrecompileColorFilter : public PrecompileBase { 45 public: PrecompileColorFilter()46 PrecompileColorFilter() : PrecompileBase(Type::kColorFilter) {} 47 48 sk_sp<PrecompileColorFilter> makeComposed(sk_sp<PrecompileColorFilter> inner) const; 49 }; 50 51 //-------------------------------------------------------------------------------------------------- 52 class PrecompileImageFilter : public PrecompileBase { 53 public: isColorFilterNode()54 virtual sk_sp<PrecompileColorFilter> isColorFilterNode() const { return nullptr; } 55 countInputs()56 int countInputs() const { return fInputs.count(); } 57 getInput(int index)58 const PrecompileImageFilter* getInput(int index) const { 59 SkASSERT(index < this->countInputs()); 60 return fInputs[index].get(); 61 } 62 63 protected: PrecompileImageFilter(SkSpan<sk_sp<PrecompileImageFilter>> inputs)64 PrecompileImageFilter(SkSpan<sk_sp<PrecompileImageFilter>> inputs) 65 : PrecompileBase(Type::kImageFilter) { 66 fInputs.reset(inputs.size()); 67 for (int i = 0; i < (int) inputs.size(); ++i) { 68 fInputs[i] = inputs[i]; 69 } 70 } 71 72 private: 73 friend class PaintOptions; // for createPipelines() access 74 75 // The PrecompileImageFilter classes do not use the PrecompileBase::addToKey virtual since 76 // they, in general, do not themselves contribute to a given SkPaint/Pipeline but, rather, 77 // create separate SkPaints/Pipelines from whole cloth (in onCreatePipelines). addToKey(const KeyContext & keyContext,PaintParamsKeyBuilder * builder,PipelineDataGatherer * gatherer,int desiredCombination)78 void addToKey(const KeyContext& keyContext, 79 PaintParamsKeyBuilder* builder, 80 PipelineDataGatherer* gatherer, 81 int desiredCombination) const final { 82 SkASSERT(false); 83 } 84 asAColorFilter()85 sk_sp<PrecompileColorFilter> asAColorFilter() const { 86 sk_sp<PrecompileColorFilter> tmp = this->isColorFilterNode(); 87 if (!tmp) { 88 return nullptr; 89 } 90 SkASSERT(this->countInputs() == 1); 91 if (this->getInput(0)) { 92 return nullptr; 93 } 94 // TODO: as in SkImageFilter::asAColorFilter, handle the special case of 95 // affectsTransparentBlack. This is tricky for precompilation since we don't, 96 // necessarily, have all the parameters of the ColorFilter in order to evaluate 97 // filterColor4f(SkColors::kTransparent) - the normal API's implementation. 98 return tmp; 99 } 100 101 virtual void onCreatePipelines(const KeyContext&, 102 PipelineDataGatherer*, 103 const PaintOptionsPriv::ProcessCombination&) const = 0; 104 createPipelines(const KeyContext & keyContext,PipelineDataGatherer * gatherer,const PaintOptionsPriv::ProcessCombination & processCombination)105 void createPipelines(const KeyContext& keyContext, 106 PipelineDataGatherer* gatherer, 107 const PaintOptionsPriv::ProcessCombination& processCombination) { 108 // TODO: we will want to mark already visited nodes to prevent loops and track 109 // already created Pipelines so we don't over-generate too much (e.g., if a DAG 110 // has multiple blurs we don't want to keep trying to create all the blur pipelines). 111 this->onCreatePipelines(keyContext, gatherer, processCombination); 112 113 for (const sk_sp<PrecompileImageFilter>& input : fInputs) { 114 if (input) { 115 input->createPipelines(keyContext, gatherer, processCombination); 116 } 117 } 118 } 119 120 skia_private::AutoSTArray<2, sk_sp<PrecompileImageFilter>> fInputs; 121 }; 122 123 class PrecompileMaskFilter : public PrecompileBase { 124 public: PrecompileMaskFilter()125 PrecompileMaskFilter() : PrecompileBase(Type::kMaskFilter) {} 126 127 private: 128 friend class PaintOptions; // for createPipelines() access 129 130 // The PrecompileMaskFilter classes do not use the PrecompileBase::addToKey virtual since 131 // they, in general, do not themselves contribute to a given SkPaint/Pipeline but, rather, 132 // create separate SkPaints/Pipelines from whole cloth (in createPipelines). addToKey(const KeyContext & keyContext,PaintParamsKeyBuilder * builder,PipelineDataGatherer * gatherer,int desiredCombination)133 void addToKey(const KeyContext& keyContext, 134 PaintParamsKeyBuilder* builder, 135 PipelineDataGatherer* gatherer, 136 int desiredCombination) const final { 137 SkASSERT(false); 138 } 139 140 virtual void createPipelines(const KeyContext&, 141 PipelineDataGatherer*, 142 const PaintOptionsPriv::ProcessCombination&) const = 0; 143 }; 144 145 } // namespace skgpu::graphite 146 147 #endif // skgpu_graphite_PrecompileInternal_DEFINED 148