/* * Copyright 2021 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "modules/skottie/src/effects/Effects.h" #include "include/effects/SkRuntimeEffect.h" #include "modules/skottie/src/Adapter.h" #include "modules/skottie/src/SkottieJson.h" #include "modules/skottie/src/SkottieValue.h" #include "modules/sksg/include/SkSGColorFilter.h" namespace skottie::internal { #ifdef SK_ENABLE_SKSL namespace { // Convert to black & white, based on input luminance and a threshold uniform. static constexpr char gThresholdSkSL[] = R"( uniform half t; half4 main(half4 color) { half4 c = unpremul(color); half lum = dot(c.rgb, half3(0.2126, 0.7152, 0.0722)), bw = step(t, lum); return bw.xxx1 * c.a; } )"; static sk_sp threshold_effect() { static const SkRuntimeEffect* effect = SkRuntimeEffect::MakeForColorFilter(SkString(gThresholdSkSL), {}).effect.release(); SkASSERT(effect); return sk_ref_sp(effect); } class ThresholdAdapter final : public DiscardableAdapterBase { public: ThresholdAdapter(const skjson::ArrayValue& jprops, sk_sp layer, const AnimationBuilder& abuilder) : INHERITED(sksg::ExternalColorFilter::Make(std::move(layer))) { enum : size_t { kLevel_Index = 0, }; EffectBinder(jprops, abuilder, this).bind(kLevel_Index, fLevel); } private: void onSync() override { auto cf = threshold_effect()->makeColorFilter(SkData::MakeWithCopy(&fLevel, sizeof(fLevel))); this->node()->setColorFilter(std::move(cf)); } ScalarValue fLevel = 0; using INHERITED = DiscardableAdapterBase; }; } // namespace #endif // SK_ENABLE_SKSL sk_sp EffectBuilder::attachThresholdEffect(const skjson::ArrayValue& jprops, sk_sp layer) const { #ifdef SK_ENABLE_SKSL return fBuilder->attachDiscardableAdapter(jprops, std::move(layer), *fBuilder); #else // TODO(skia:12197) return layer; #endif } } // namespace skottie::internal