xref: /aosp_15_r20/external/skia/modules/skottie/src/SlotManager.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2023 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "modules/skottie/include/SlotManager.h"
9 
10 #include "include/core/SkImage.h"
11 #include "include/core/SkM44.h"
12 #include "include/core/SkMatrix.h"
13 #include "include/core/SkSamplingOptions.h"
14 #include "modules/skottie/include/SkottieProperty.h"
15 #include "modules/skottie/src/SkottiePriv.h"
16 #include "modules/skottie/src/animator/Animator.h"
17 #include "modules/skottie/src/text/TextAdapter.h"
18 #include "modules/skresources/include/SkResources.h"
19 
20 #include <utility>
21 
22 class skottie::SlotManager::ImageAssetProxy final : public skresources::ImageAsset {
23 public:
ImageAssetProxy(sk_sp<skresources::ImageAsset> asset)24     explicit ImageAssetProxy(sk_sp<skresources::ImageAsset> asset)
25     : fImageAsset(std::move(asset)) {}
26 
27     // always returns true to force the FootageLayer to always redraw in case asset is swapped
isMultiFrame()28     bool isMultiFrame() override { return true; }
29 
getFrameData(float t)30     FrameData getFrameData(float t) override {
31         if (fImageAsset) {
32             return fImageAsset->getFrameData(t);
33         }
34         return {nullptr , SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNearest),
35             SkMatrix::I(), SizeFit::kCenter};
36     }
37 
setImageAsset(sk_sp<skresources::ImageAsset> asset)38     void setImageAsset (sk_sp<skresources::ImageAsset> asset) {
39         fImageAsset = std::move(asset);
40     }
41 
getImageAsset() const42     sk_sp<const skresources::ImageAsset> getImageAsset() const {
43         return fImageAsset;
44     }
45 private:
46     sk_sp<skresources::ImageAsset> fImageAsset;
47 };
48 
SlotManager(sk_sp<skottie::internal::SceneGraphRevalidator> revalidator)49 skottie::SlotManager::SlotManager(sk_sp<skottie::internal::SceneGraphRevalidator> revalidator)
50         : fRevalidator(std::move(revalidator)) {}
51 
52 skottie::SlotManager::~SlotManager() = default;
53 
setColorSlot(const SlotID & slotID,SkColor c)54 bool skottie::SlotManager::setColorSlot(const SlotID& slotID, SkColor c) {
55     auto c4f = SkColor4f::FromColor(c);
56     ColorValue v{c4f.fR, c4f.fG, c4f.fB, c4f.fA};
57     const auto valueGroup = fColorMap.find(slotID);
58     if (valueGroup) {
59         for (auto& cPair : *valueGroup) {
60             *(cPair.value) = v;
61             cPair.adapter->onSync();
62         }
63         fRevalidator->revalidate();
64         return true;
65     }
66     return false;
67 }
68 
setImageSlot(const SlotID & slotID,const sk_sp<skresources::ImageAsset> & i)69 bool skottie::SlotManager::setImageSlot(const SlotID& slotID,
70                                         const sk_sp<skresources::ImageAsset>& i) {
71     const auto imageGroup = fImageMap.find(slotID);
72     if (imageGroup) {
73         for (auto& imageAsset : *imageGroup) {
74             imageAsset->setImageAsset(i);
75         }
76         fRevalidator->revalidate();
77         return true;
78     }
79     return false;
80 }
81 
setScalarSlot(const SlotID & slotID,float s)82 bool skottie::SlotManager::setScalarSlot(const SlotID& slotID, float s) {
83     const auto valueGroup = fScalarMap.find(slotID);
84     if (valueGroup) {
85         for (auto& sPair : *valueGroup) {
86             *(sPair.value) = s;
87             sPair.adapter->onSync();
88         }
89         fRevalidator->revalidate();
90         return true;
91     }
92     return false;
93 }
94 
setVec2Slot(const SlotID & slotID,SkV2 v)95 bool skottie::SlotManager::setVec2Slot(const SlotID& slotID, SkV2 v) {
96     const auto valueGroup = fVec2Map.find(slotID);
97     if (valueGroup) {
98         for (auto& vPair : *valueGroup) {
99             *(vPair.value) = v;
100             vPair.adapter->onSync();
101         }
102         fRevalidator->revalidate();
103         return true;
104     }
105     return false;
106 }
107 
setTextSlot(const SlotID & slotID,const TextPropertyValue & t)108 bool skottie::SlotManager::setTextSlot(const SlotID& slotID, const TextPropertyValue& t) {
109     const auto adapterGroup = fTextMap.find(slotID);
110     if (adapterGroup) {
111         for (auto& textAdapter : *adapterGroup) {
112             textAdapter->setText(t);
113         }
114         fRevalidator->revalidate();
115         return true;
116     }
117     return false;
118 }
119 
getColorSlot(const SlotID & slotID) const120 std::optional<SkColor> skottie::SlotManager::getColorSlot(const SlotID& slotID) const {
121     const auto valueGroup = fColorMap.find(slotID);
122     return valueGroup && !valueGroup->empty() ? std::optional<SkColor>(*(valueGroup->at(0).value))
123                                               : std::nullopt;
124 }
125 
getImageSlot(const SlotID & slotID) const126 sk_sp<const skresources::ImageAsset> skottie::SlotManager::getImageSlot(
127         const SlotID& slotID) const {
128     const auto imageGroup = fImageMap.find(slotID);
129     return imageGroup && !imageGroup->empty() ? imageGroup->at(0)->getImageAsset() : nullptr;
130 }
131 
getScalarSlot(const SlotID & slotID) const132 std::optional<float> skottie::SlotManager::getScalarSlot(const SlotID& slotID) const {
133     const auto valueGroup = fScalarMap.find(slotID);
134     return valueGroup && !valueGroup->empty() ? std::optional<float>(*(valueGroup->at(0).value))
135                                               : std::nullopt;
136 }
137 
getVec2Slot(const SlotID & slotID) const138 std::optional<SkV2> skottie::SlotManager::getVec2Slot(const SlotID& slotID) const {
139     const auto valueGroup = fVec2Map.find(slotID);
140     return valueGroup && !valueGroup->empty() ? std::optional<SkV2>(*(valueGroup->at(0).value))
141                                               : std::nullopt;
142 }
143 
getTextSlot(const SlotID & slotID) const144 std::optional<skottie::TextPropertyValue> skottie::SlotManager::getTextSlot(
145         const SlotID& slotID) const {
146     const auto adapterGroup = fTextMap.find(slotID);
147     return adapterGroup && !adapterGroup->empty() ?
148            std::optional<TextPropertyValue>(adapterGroup->at(0)->getText()) :
149            std::nullopt;
150 }
151 
trackColorValue(const SlotID & slotID,ColorValue * colorValue,sk_sp<internal::AnimatablePropertyContainer> adapter)152 void skottie::SlotManager::trackColorValue(const SlotID& slotID, ColorValue* colorValue,
153                                            sk_sp<internal::AnimatablePropertyContainer> adapter) {
154     fColorMap[slotID].push_back({colorValue, std::move(adapter)});
155 }
156 
trackImageValue(const SlotID & slotID,sk_sp<skresources::ImageAsset> imageAsset)157 sk_sp<skresources::ImageAsset> skottie::SlotManager::trackImageValue(const SlotID& slotID,
158                                                                      sk_sp<skresources::ImageAsset>
159                                                                         imageAsset) {
160     auto proxy = sk_make_sp<ImageAssetProxy>(std::move(imageAsset));
161     fImageMap[slotID].push_back(proxy);
162     return proxy;
163 }
164 
trackScalarValue(const SlotID & slotID,ScalarValue * scalarValue,sk_sp<internal::AnimatablePropertyContainer> adapter)165 void skottie::SlotManager::trackScalarValue(const SlotID& slotID, ScalarValue* scalarValue,
166                                             sk_sp<internal::AnimatablePropertyContainer> adapter) {
167     fScalarMap[slotID].push_back({scalarValue, std::move(adapter)});
168 }
169 
trackVec2Value(const SlotID & slotID,Vec2Value * vec2Value,sk_sp<internal::AnimatablePropertyContainer> adapter)170 void skottie::SlotManager::trackVec2Value(const SlotID& slotID, Vec2Value* vec2Value,
171                                           sk_sp<internal::AnimatablePropertyContainer> adapter) {
172     fVec2Map[slotID].push_back({vec2Value, std::move(adapter)});
173 }
174 
trackTextValue(const SlotID & slotID,sk_sp<internal::TextAdapter> adapter)175 void skottie::SlotManager::trackTextValue(const SlotID& slotID,
176                                           sk_sp<internal::TextAdapter> adapter) {
177     fTextMap[slotID].push_back(std::move(adapter));
178 }
179 
getSlotInfo() const180 skottie::SlotManager::SlotInfo skottie::SlotManager::getSlotInfo() const {
181     SlotInfo sInfo;
182     for (const auto& c : fColorMap) {
183         sInfo.fColorSlotIDs.push_back(c.first);
184     }
185     for (const auto& s : fScalarMap) {
186         sInfo.fScalarSlotIDs.push_back(s.first);
187     }
188     for (const auto& v : fVec2Map) {
189         sInfo.fVec2SlotIDs.push_back(v.first);
190     }
191     for (const auto& i : fImageMap) {
192         sInfo.fImageSlotIDs.push_back(i.first);
193     }
194     for (const auto& t : fTextMap) {
195         sInfo.fTextSlotIDs.push_back(t.first);
196     }
197     return sInfo;
198 }
199