| /* | |
| * Copyright 2021 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/SkData.h" | |
| #include "include/core/SkRefCnt.h" | |
| #include "include/core/SkString.h" | |
| #include "include/effects/SkRuntimeEffect.h" | |
| #include "include/private/SkAssert.h" | |
| #include "modules/skottie/src/Adapter.h" | |
| #include "modules/skottie/src/SkottiePriv.h" | |
| #include "modules/skottie/src/SkottieValue.h" | |
| #include "modules/skottie/src/effects/Effects.h" | |
| #include "modules/sksg/include/SkSGColorFilter.h" | |
| #include "modules/sksg/include/SkSGRenderNode.h" | |
| #include <cstddef> | |
| #include <utility> | |
| namespace skjson { | |
| class ArrayValue; | |
| } | |
| namespace skottie::internal { | |
| namespace { | |
| // Convert to black & white, based on input luminance and a threshold uniform. | |
| static constexpr char gThresholdSkSL[] = | |
| "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<SkRuntimeEffect> threshold_effect() { | |
| static const SkRuntimeEffect* effect = | |
| SkRuntimeEffect::MakeForColorFilter(SkString(gThresholdSkSL), {}).effect.release(); | |
| SkASSERT(effect); | |
| return sk_ref_sp(effect); | |
| } | |
| class ThresholdAdapter final : public DiscardableAdapterBase<ThresholdAdapter, | |
| sksg::ExternalColorFilter> { | |
| public: | |
| ThresholdAdapter(const skjson::ArrayValue& jprops, | |
| sk_sp<sksg::RenderNode> 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<ThresholdAdapter, sksg::ExternalColorFilter>; | |
| }; | |
| } // namespace | |
| sk_sp<sksg::RenderNode> EffectBuilder::attachThresholdEffect(const skjson::ArrayValue& jprops, | |
| sk_sp<sksg::RenderNode> layer) const { | |
| return fBuilder->attachDiscardableAdapter<ThresholdAdapter>(jprops, | |
| std::move(layer), | |
| *fBuilder); | |
| } | |
| } // namespace skottie::internal |