1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2019 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTileMode.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTPin.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/src/SkottiePriv.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/src/SkottieValue.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/src/animator/Animator.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "modules/skottie/src/effects/Effects.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "modules/sksg/include/SkSGRenderEffect.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "modules/sksg/include/SkSGRenderNode.h"
18*c8dee2aaSAndroid Build Coastguard Worker
19*c8dee2aaSAndroid Build Coastguard Worker #include <array>
20*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
21*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
22*c8dee2aaSAndroid Build Coastguard Worker
23*c8dee2aaSAndroid Build Coastguard Worker namespace skjson {
24*c8dee2aaSAndroid Build Coastguard Worker class ArrayValue;
25*c8dee2aaSAndroid Build Coastguard Worker }
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker namespace skottie {
28*c8dee2aaSAndroid Build Coastguard Worker namespace internal {
29*c8dee2aaSAndroid Build Coastguard Worker
30*c8dee2aaSAndroid Build Coastguard Worker namespace {
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker class GaussianBlurEffectAdapter final : public AnimatablePropertyContainer {
33*c8dee2aaSAndroid Build Coastguard Worker public:
Make(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer,const AnimationBuilder * abuilder)34*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GaussianBlurEffectAdapter> Make(const skjson::ArrayValue& jprops,
35*c8dee2aaSAndroid Build Coastguard Worker sk_sp<sksg::RenderNode> layer,
36*c8dee2aaSAndroid Build Coastguard Worker const AnimationBuilder* abuilder) {
37*c8dee2aaSAndroid Build Coastguard Worker return sk_sp<GaussianBlurEffectAdapter>(new GaussianBlurEffectAdapter(jprops,
38*c8dee2aaSAndroid Build Coastguard Worker std::move(layer),
39*c8dee2aaSAndroid Build Coastguard Worker abuilder));
40*c8dee2aaSAndroid Build Coastguard Worker }
41*c8dee2aaSAndroid Build Coastguard Worker
node() const42*c8dee2aaSAndroid Build Coastguard Worker const sk_sp<sksg::RenderNode>& node() const { return fImageFilterEffect; }
43*c8dee2aaSAndroid Build Coastguard Worker
44*c8dee2aaSAndroid Build Coastguard Worker private:
GaussianBlurEffectAdapter(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer,const AnimationBuilder * abuilder)45*c8dee2aaSAndroid Build Coastguard Worker GaussianBlurEffectAdapter(const skjson::ArrayValue& jprops,
46*c8dee2aaSAndroid Build Coastguard Worker sk_sp<sksg::RenderNode> layer,
47*c8dee2aaSAndroid Build Coastguard Worker const AnimationBuilder* abuilder)
48*c8dee2aaSAndroid Build Coastguard Worker : fBlur(sksg::BlurImageFilter::Make())
49*c8dee2aaSAndroid Build Coastguard Worker , fImageFilterEffect(sksg::ImageFilterEffect::Make(std::move(layer), fBlur)) {
50*c8dee2aaSAndroid Build Coastguard Worker enum : size_t {
51*c8dee2aaSAndroid Build Coastguard Worker kBlurriness_Index = 0,
52*c8dee2aaSAndroid Build Coastguard Worker kDimensions_Index = 1,
53*c8dee2aaSAndroid Build Coastguard Worker kRepeatEdge_Index = 2,
54*c8dee2aaSAndroid Build Coastguard Worker };
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker EffectBinder(jprops, *abuilder, this)
57*c8dee2aaSAndroid Build Coastguard Worker .bind(kBlurriness_Index, fBlurriness)
58*c8dee2aaSAndroid Build Coastguard Worker .bind(kDimensions_Index, fDimensions)
59*c8dee2aaSAndroid Build Coastguard Worker .bind(kRepeatEdge_Index, fRepeatEdge);
60*c8dee2aaSAndroid Build Coastguard Worker }
61*c8dee2aaSAndroid Build Coastguard Worker
onSync()62*c8dee2aaSAndroid Build Coastguard Worker void onSync() override {
63*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkVector kDimensionsMap[] = {
64*c8dee2aaSAndroid Build Coastguard Worker { 1, 1 }, // 1 -> horizontal and vertical
65*c8dee2aaSAndroid Build Coastguard Worker { 1, 0 }, // 2 -> horizontal
66*c8dee2aaSAndroid Build Coastguard Worker { 0, 1 }, // 3 -> vertical
67*c8dee2aaSAndroid Build Coastguard Worker };
68*c8dee2aaSAndroid Build Coastguard Worker
69*c8dee2aaSAndroid Build Coastguard Worker const auto dim_index = SkTPin<size_t>(static_cast<size_t>(fDimensions),
70*c8dee2aaSAndroid Build Coastguard Worker 1, std::size(kDimensionsMap)) - 1;
71*c8dee2aaSAndroid Build Coastguard Worker
72*c8dee2aaSAndroid Build Coastguard Worker const auto sigma = fBlurriness * kBlurSizeToSigma;
73*c8dee2aaSAndroid Build Coastguard Worker
74*c8dee2aaSAndroid Build Coastguard Worker fBlur->setSigma({ sigma * kDimensionsMap[dim_index].x(),
75*c8dee2aaSAndroid Build Coastguard Worker sigma * kDimensionsMap[dim_index].y() });
76*c8dee2aaSAndroid Build Coastguard Worker
77*c8dee2aaSAndroid Build Coastguard Worker // 0 -> repeat edge pixels: off
78*c8dee2aaSAndroid Build Coastguard Worker // 1 -> repeat edge pixels: on
79*c8dee2aaSAndroid Build Coastguard Worker const auto repeat_edge = static_cast<bool>(fRepeatEdge);
80*c8dee2aaSAndroid Build Coastguard Worker
81*c8dee2aaSAndroid Build Coastguard Worker // Repeat edge pixels implies two things:
82*c8dee2aaSAndroid Build Coastguard Worker // - the blur uses kClamp tiling
83*c8dee2aaSAndroid Build Coastguard Worker // - the output is cropped to content size
84*c8dee2aaSAndroid Build Coastguard Worker fBlur->setTileMode(repeat_edge
85*c8dee2aaSAndroid Build Coastguard Worker ? SkTileMode::kClamp
86*c8dee2aaSAndroid Build Coastguard Worker : SkTileMode::kDecal);
87*c8dee2aaSAndroid Build Coastguard Worker static_cast<sksg::ImageFilterEffect*>(fImageFilterEffect.get())->setCropping(repeat_edge
88*c8dee2aaSAndroid Build Coastguard Worker ? sksg::ImageFilterEffect::Cropping::kContent
89*c8dee2aaSAndroid Build Coastguard Worker : sksg::ImageFilterEffect::Cropping::kNone);
90*c8dee2aaSAndroid Build Coastguard Worker }
91*c8dee2aaSAndroid Build Coastguard Worker
92*c8dee2aaSAndroid Build Coastguard Worker const sk_sp<sksg::BlurImageFilter> fBlur;
93*c8dee2aaSAndroid Build Coastguard Worker const sk_sp<sksg::RenderNode> fImageFilterEffect;
94*c8dee2aaSAndroid Build Coastguard Worker
95*c8dee2aaSAndroid Build Coastguard Worker ScalarValue fBlurriness = 0, // Controls the blur sigma.
96*c8dee2aaSAndroid Build Coastguard Worker fDimensions = 1, // 1 -> horizontal & vertical, 2 -> horizontal, 3 -> vertical
97*c8dee2aaSAndroid Build Coastguard Worker fRepeatEdge = 0; // 0 -> clamp, 1 -> repeat
98*c8dee2aaSAndroid Build Coastguard Worker };
99*c8dee2aaSAndroid Build Coastguard Worker
100*c8dee2aaSAndroid Build Coastguard Worker } // namespace
101*c8dee2aaSAndroid Build Coastguard Worker
attachGaussianBlurEffect(const skjson::ArrayValue & jprops,sk_sp<sksg::RenderNode> layer) const102*c8dee2aaSAndroid Build Coastguard Worker sk_sp<sksg::RenderNode> EffectBuilder::attachGaussianBlurEffect(
103*c8dee2aaSAndroid Build Coastguard Worker const skjson::ArrayValue& jprops,
104*c8dee2aaSAndroid Build Coastguard Worker sk_sp<sksg::RenderNode> layer) const {
105*c8dee2aaSAndroid Build Coastguard Worker return fBuilder->attachDiscardableAdapter<GaussianBlurEffectAdapter>(jprops,
106*c8dee2aaSAndroid Build Coastguard Worker std::move(layer),
107*c8dee2aaSAndroid Build Coastguard Worker fBuilder);
108*c8dee2aaSAndroid Build Coastguard Worker }
109*c8dee2aaSAndroid Build Coastguard Worker
110*c8dee2aaSAndroid Build Coastguard Worker } // namespace internal
111*c8dee2aaSAndroid Build Coastguard Worker } // namespace skottie
112