/* * Copyright 2022 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef skgpu_graphite_Precompile_DEFINED #define skgpu_graphite_Precompile_DEFINED #include "include/core/SkBlendMode.h" #include "include/core/SkRefCnt.h" #include "include/core/SkSpan.h" #include #include #include class SkRuntimeEffect; namespace skgpu::graphite { class KeyContext; class PrecompileBasePriv; class UniquePaintParamsID; class PrecompileBase : public SkRefCnt { public: enum class Type { kBlender, kColorFilter, kImageFilter, kMaskFilter, kShader, // TODO: add others: kDrawable, kPathEffect (?!) }; PrecompileBase(Type type) : fType(type) {} Type type() const { return fType; } // TODO: Maybe convert these two to be parameters passed into PrecompileBase from all the // derived classes and then make them non-virtual. virtual int numIntrinsicCombinations() const { return 1; } virtual int numChildCombinations() const { return 1; } int numCombinations() const { return this->numIntrinsicCombinations() * this->numChildCombinations(); } // Provides access to functions that aren't part of the public API. PrecompileBasePriv priv(); const PrecompileBasePriv priv() const; // NOLINT(readability-const-return-type) protected: // In general, derived classes should use AddToKey to select the desired child option from // a vector and then have it added to the key with its reduced/nested child option. template static void AddToKey(const KeyContext&, PaintParamsKeyBuilder*, const std::vector>& options, int desiredOption); private: friend class PaintOptions; friend class PrecompileBasePriv; virtual bool isALocalMatrixShader() const { return false; } virtual void addToKey(const KeyContext&, int desiredCombination, PaintParamsKeyBuilder*) const = 0; Type fType; }; //-------------------------------------------------------------------------------------------------- template void PrecompileBase::AddToKey(const KeyContext& keyContext, PaintParamsKeyBuilder* builder, const std::vector>& options, int desiredOption) { for (const sk_sp& option : options) { if (desiredOption < option->numCombinations()) { option->priv().addToKey(keyContext, desiredOption, builder); break; } desiredOption -= option->numCombinations(); } } //-------------------------------------------------------------------------------------------------- class PrecompileColorFilter; class PrecompileShader : public PrecompileBase { public: PrecompileShader() : PrecompileBase(Type::kShader) {} sk_sp makeWithLocalMatrix(); sk_sp makeWithColorFilter(sk_sp); }; class PrecompileMaskFilter : public PrecompileBase { public: PrecompileMaskFilter() : PrecompileBase(Type::kMaskFilter) {} }; class PrecompileColorFilter : public PrecompileBase { public: PrecompileColorFilter() : PrecompileBase(Type::kColorFilter) {} }; class PrecompileImageFilter : public PrecompileBase { public: PrecompileImageFilter() : PrecompileBase(Type::kImageFilter) {} }; class PrecompileBlender : public PrecompileBase { public: PrecompileBlender() : PrecompileBase(Type::kBlender) {} virtual std::optional asBlendMode() const { return {}; } static sk_sp Mode(SkBlendMode); }; //-------------------------------------------------------------------------------------------------- class PaintOptionsPriv; class PaintOptions { public: void setShaders(SkSpan> shaders) { fShaderOptions.assign(shaders.begin(), shaders.end()); } void setMaskFilters(SkSpan> maskFilters) { fMaskFilterOptions.assign(maskFilters.begin(), maskFilters.end()); } void setColorFilters(SkSpan> colorFilters) { fColorFilterOptions.assign(colorFilters.begin(), colorFilters.end()); } void setImageFilters(SkSpan> imageFilters) { fImageFilterOptions.assign(imageFilters.begin(), imageFilters.end()); } void setBlendModes(SkSpan blendModes) { fBlenderOptions.reserve(blendModes.size()); for (SkBlendMode bm : blendModes) { fBlenderOptions.emplace_back(PrecompileBlender::Mode(bm)); } } void setBlenders(SkSpan> blenders) { fBlenderOptions.assign(blenders.begin(), blenders.end()); } // Provides access to functions that aren't part of the public API. PaintOptionsPriv priv(); const PaintOptionsPriv priv() const; // NOLINT(readability-const-return-type) private: friend class PaintOptionsPriv; int numShaderCombinations() const; int numMaskFilterCombinations() const; int numColorFilterCombinations() const; // TODO: need to decompose imagefilters into component draws int numBlendModeCombinations() const; int numCombinations() const; // 'desiredCombination' must be less than the result of the numCombinations call void createKey(const KeyContext&, int desiredCombination, PaintParamsKeyBuilder*, bool addPrimitiveBlender) const; void buildCombinations( const KeyContext&, bool addPrimitiveBlender, const std::function& processCombination) const; std::vector> fShaderOptions; std::vector> fMaskFilterOptions; std::vector> fColorFilterOptions; std::vector> fImageFilterOptions; std::vector> fBlenderOptions; }; } // namespace skgpu::graphite #endif // skgpu_graphite_Precompile_DEFINED