blob: 9cb6f6688933293e7e80e15e0699ab5a294041cb [file] [log] [blame]
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkTypes.h"
#ifdef SK_ENABLE_PRECOMPILE
#include "src/gpu/graphite/FactoryFunctions.h"
#include "src/gpu/graphite/Precompile.h"
namespace skgpu::graphite {
//--------------------------------------------------------------------------------------------------
class PrecompileBlendModeBlender : public PrecompileBlender {
public:
PrecompileBlendModeBlender(SkBlendMode blendMode) : fBlendMode(blendMode) {}
std::optional<SkBlendMode> asBlendMode() const final { return fBlendMode; }
private:
SkBlendMode fBlendMode;
};
sk_sp<PrecompileBlender> PrecompileBlender::Mode(SkBlendMode blendMode) {
return sk_make_sp<PrecompileBlendModeBlender>(blendMode);
}
//--------------------------------------------------------------------------------------------------
class BlendPrecompileShader : public PrecompileShader {
public:
BlendPrecompileShader(SkSpan<const sk_sp<PrecompileBlender>> blenders,
SkSpan<const sk_sp<PrecompileShader>> dsts,
SkSpan<const sk_sp<PrecompileShader>> srcs)
: fBlenders(blenders.begin(), blenders.end())
, fDsts(dsts.begin(), dsts.end())
, fSrcs(srcs.begin(), srcs.end()) {
}
private:
std::vector<sk_sp<PrecompileBlender>> fBlenders;
std::vector<sk_sp<PrecompileShader>> fDsts;
std::vector<sk_sp<PrecompileShader>> fSrcs;
};
//--------------------------------------------------------------------------------------------------
sk_sp<PrecompileShader> PrecompileShaders::Color() {
return sk_make_sp<PrecompileShader>();
}
sk_sp<PrecompileShader> PrecompileShaders::Blend(
SkSpan<const sk_sp<PrecompileBlender>> blenders,
SkSpan<const sk_sp<PrecompileShader>> dsts,
SkSpan<const sk_sp<PrecompileShader>> srcs) {
return sk_make_sp<BlendPrecompileShader>(std::move(blenders),
std::move(dsts), std::move(srcs));
}
sk_sp<PrecompileShader> PrecompileShaders::Blend(
SkSpan<SkBlendMode> blendModes,
SkSpan<const sk_sp<PrecompileShader>> dsts,
SkSpan<const sk_sp<PrecompileShader>> srcs) {
std::vector<sk_sp<PrecompileBlender>> tmp;
tmp.reserve(blendModes.size());
for (SkBlendMode bm : blendModes) {
tmp.emplace_back(PrecompileBlender::Mode(bm));
}
return sk_make_sp<BlendPrecompileShader>(tmp, std::move(dsts), std::move(srcs));
}
sk_sp<PrecompileShader> PrecompileShaders::Image() {
return sk_make_sp<PrecompileShader>();
}
sk_sp<PrecompileShader> PrecompileShaders::LinearGradient() {
return sk_make_sp<PrecompileShader>();
}
sk_sp<PrecompileShader> PrecompileShaders::RadialGradient() {
return sk_make_sp<PrecompileShader>();
}
sk_sp<PrecompileShader> PrecompileShaders::TwoPointConicalGradient() {
return sk_make_sp<PrecompileShader>();
}
sk_sp<PrecompileShader> PrecompileShaders::SweepGradient() {
return sk_make_sp<PrecompileShader>();
}
//--------------------------------------------------------------------------------------------------
sk_sp<PrecompileMaskFilter> PrecompileMaskFilters::Blur() {
return sk_make_sp<PrecompileMaskFilter>();
}
//--------------------------------------------------------------------------------------------------
sk_sp<PrecompileColorFilter> PrecompileColorFilters::Matrix() {
return sk_make_sp<PrecompileColorFilter>();
}
//--------------------------------------------------------------------------------------------------
sk_sp<PrecompileImageFilter> PrecompileImageFilters::Blur() {
return sk_make_sp<PrecompileImageFilter>();
}
sk_sp<PrecompileImageFilter> PrecompileImageFilters::Image() {
return sk_make_sp<PrecompileImageFilter>();
}
//--------------------------------------------------------------------------------------------------
PrecompileChildPtr::PrecompileChildPtr(sk_sp<PrecompileShader> s) : fChild(std::move(s)) {}
PrecompileChildPtr::PrecompileChildPtr(sk_sp<PrecompileColorFilter> cf)
: fChild(std::move(cf)) {
}
PrecompileChildPtr::PrecompileChildPtr(sk_sp<PrecompileBlender> b) : fChild(std::move(b)) {}
namespace {
#ifdef SK_DEBUG
bool precompilebase_is_valid_as_child(const PrecompileBase *child) {
if (!child) {
return true;
}
switch (child->type()) {
case PrecompileBase::Type::kShader:
case PrecompileBase::Type::kColorFilter:
case PrecompileBase::Type::kBlender:
return true;
default:
return false;
}
}
#endif // SK_DEBUG
}
PrecompileChildPtr::PrecompileChildPtr(sk_sp<PrecompileBase> child)
: fChild(std::move(child)) {
SkASSERT(precompilebase_is_valid_as_child(fChild.get()));
}
std::optional<SkRuntimeEffect::ChildType> PrecompileChildPtr::type() const {
if (fChild) {
switch (fChild->type()) {
case PrecompileBase::Type::kShader:
return SkRuntimeEffect::ChildType::kShader;
case PrecompileBase::Type::kColorFilter:
return SkRuntimeEffect::ChildType::kColorFilter;
case PrecompileBase::Type::kBlender:
return SkRuntimeEffect::ChildType::kBlender;
default:
break;
}
}
return std::nullopt;
}
PrecompileShader* PrecompileChildPtr::shader() const {
return (fChild && fChild->type() == PrecompileBase::Type::kShader)
? static_cast<PrecompileShader*>(fChild.get())
: nullptr;
}
PrecompileColorFilter* PrecompileChildPtr::colorFilter() const {
return (fChild && fChild->type() == PrecompileBase::Type::kColorFilter)
? static_cast<PrecompileColorFilter*>(fChild.get())
: nullptr;
}
PrecompileBlender* PrecompileChildPtr::blender() const {
return (fChild && fChild->type() == PrecompileBase::Type::kBlender)
? static_cast<PrecompileBlender*>(fChild.get())
: nullptr;
}
//--------------------------------------------------------------------------------------------------
template<typename T>
class PrecompileRTEffect : public T {
public:
PrecompileRTEffect(sk_sp<SkRuntimeEffect> effect,
SkSpan<const PrecompileChildOptions> childOptions)
: fEffect(std::move(effect)) {
fChildOptions.reserve(childOptions.size());
for (PrecompileChildOptions c : childOptions) {
fChildOptions.push_back({ c.begin(), c.end() });
}
}
private:
sk_sp<SkRuntimeEffect> fEffect;
std::vector<std::vector<PrecompileChildPtr>> fChildOptions;
};
sk_sp<PrecompileShader> MakePrecompileShader(
sk_sp<SkRuntimeEffect> effect,
SkSpan<const PrecompileChildOptions> childOptions) {
// TODO: check that 'effect' has the kAllowShader_Flag bit set and:
// for each entry in childOptions:
// all the SkPrecompileChildPtrs have the same type as the corresponding child in the effect
return sk_make_sp<PrecompileRTEffect<PrecompileShader>>(std::move(effect), childOptions);
}
sk_sp<PrecompileColorFilter> MakePrecompileColorFilter(
sk_sp<SkRuntimeEffect> effect,
SkSpan<const PrecompileChildOptions> childOptions) {
// TODO: check that 'effect' has the kAllowColorFilter_Flag bit set and:
// for each entry in childOptions:
// all the SkPrecompileChildPtrs have the same type as the corresponding child in the effect
return sk_make_sp<PrecompileRTEffect<PrecompileColorFilter>>(std::move(effect),
childOptions);
}
sk_sp<PrecompileBlender> MakePrecompileBlender(
sk_sp<SkRuntimeEffect> effect,
SkSpan<const PrecompileChildOptions> childOptions) {
// TODO: check that 'effect' has the kAllowBlender_Flag bit set and:
// for each entry in childOptions:
// all the SkPrecompileChildPtrs have the same type as the corresponding child in the effect
return sk_make_sp<PrecompileRTEffect<PrecompileBlender>>(std::move(effect), childOptions);
}
} // namespace skgpu::graphite
//--------------------------------------------------------------------------------------------------
#endif // SK_ENABLE_PRECOMPILE