blob: ac1d7c7ee3920cbd48a5d5b1d82fb8d13bc7e91c [file] [log] [blame]
/*
* Copyright 2019 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/private/SkTPin.h"
#include "modules/skottie/src/SkottieValue.h"
#include "modules/sksg/include/SkSGRenderEffect.h"
#include "src/utils/SkJSON.h"
namespace skottie {
namespace internal {
namespace {
class GaussianBlurEffectAdapter final : public AnimatablePropertyContainer {
public:
static sk_sp<GaussianBlurEffectAdapter> Make(const skjson::ArrayValue& jprops,
sk_sp<sksg::RenderNode> layer,
const AnimationBuilder* abuilder) {
return sk_sp<GaussianBlurEffectAdapter>(new GaussianBlurEffectAdapter(jprops,
std::move(layer),
abuilder));
}
const sk_sp<sksg::RenderNode>& node() const { return fImageFilterEffect; }
private:
GaussianBlurEffectAdapter(const skjson::ArrayValue& jprops,
sk_sp<sksg::RenderNode> layer,
const AnimationBuilder* abuilder)
: fBlur(sksg::BlurImageFilter::Make())
, fImageFilterEffect(sksg::ImageFilterEffect::Make(std::move(layer), fBlur)) {
enum : size_t {
kBlurriness_Index = 0,
kDimensions_Index = 1,
kRepeatEdge_Index = 2,
};
EffectBinder(jprops, *abuilder, this)
.bind(kBlurriness_Index, fBlurriness)
.bind(kDimensions_Index, fDimensions)
.bind(kRepeatEdge_Index, fRepeatEdge);
}
void onSync() override {
static constexpr SkVector kDimensionsMap[] = {
{ 1, 1 }, // 1 -> horizontal and vertical
{ 1, 0 }, // 2 -> horizontal
{ 0, 1 }, // 3 -> vertical
};
const auto dim_index = SkTPin<size_t>(static_cast<size_t>(fDimensions),
1, SK_ARRAY_COUNT(kDimensionsMap)) - 1;
const auto sigma = fBlurriness * kBlurSizeToSigma;
fBlur->setSigma({ sigma * kDimensionsMap[dim_index].x(),
sigma * kDimensionsMap[dim_index].y() });
static constexpr SkTileMode kRepeatEdgeMap[] = {
SkTileMode::kDecal, // 0 -> repeat edge pixels: off
SkTileMode::kClamp, // 1 -> repeat edge pixels: on
};
const auto repeat_index = SkTPin<size_t>(static_cast<size_t>(fRepeatEdge),
0, SK_ARRAY_COUNT(kRepeatEdgeMap) - 1);
fBlur->setTileMode(kRepeatEdgeMap[repeat_index]);
}
const sk_sp<sksg::BlurImageFilter> fBlur;
const sk_sp<sksg::RenderNode> fImageFilterEffect;
ScalarValue fBlurriness = 0, // Controls the blur sigma.
fDimensions = 1, // 1 -> horizontal & vertical, 2 -> horizontal, 3 -> vertical
fRepeatEdge = 0; // 0 -> clamp, 1 -> repeat
};
} // namespace
sk_sp<sksg::RenderNode> EffectBuilder::attachGaussianBlurEffect(
const skjson::ArrayValue& jprops,
sk_sp<sksg::RenderNode> layer) const {
return fBuilder->attachDiscardableAdapter<GaussianBlurEffectAdapter>(jprops,
std::move(layer),
fBuilder);
}
} // namespace internal
} // namespace skottie