1 /* 2 * Copyright 2017 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 #ifndef Skottie_DEFINED 9 #define Skottie_DEFINED 10 11 #include "include/core/SkFontMgr.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/core/SkSize.h" 14 #include "include/core/SkString.h" 15 #include "include/core/SkTypes.h" 16 #include "modules/skresources/include/SkResources.h" 17 18 #include <memory> 19 20 class SkCanvas; 21 struct SkRect; 22 class SkStream; 23 24 namespace skjson { class ObjectValue; } 25 26 namespace sksg { 27 28 class InvalidationController; 29 class Scene; 30 31 } // namespace sksg 32 33 namespace skottie { 34 35 using ImageAsset = skresources::ImageAsset; 36 using ResourceProvider = skresources::ResourceProvider; 37 38 class PropertyObserver; 39 40 /** 41 * A Logger subclass can be used to receive Animation::Builder parsing errors and warnings. 42 */ 43 class SK_API Logger : public SkRefCnt { 44 public: 45 enum class Level { 46 kWarning, 47 kError, 48 }; 49 50 virtual void log(Level, const char message[], const char* json = nullptr); 51 }; 52 53 /** 54 * Interface for receiving AE composition markers at Animation build time. 55 */ 56 class SK_API MarkerObserver : public SkRefCnt { 57 public: 58 // t0,t1 are in the Animation::seek() domain. 59 virtual void onMarker(const char name[], float t0, float t1) = 0; 60 }; 61 62 class SK_API Animation : public SkNVRefCnt<Animation> { 63 public: 64 65 class Builder final { 66 public: 67 enum Flags : uint32_t { 68 kDeferImageLoading = 0x01, // Normally, all static image frames are resolved at 69 // load time via ImageAsset::getFrame(0). With this flag, 70 // frames are only resolved when needed, at seek() time. 71 }; 72 73 explicit Builder(uint32_t flags = 0); 74 ~Builder(); 75 76 struct Stats { 77 float fTotalLoadTimeMS = 0, // Total animation instantiation time. 78 fJsonParseTimeMS = 0, // Time spent building a JSON DOM. 79 fSceneParseTimeMS = 0; // Time spent constructing the animation scene graph. 80 size_t fJsonSize = 0, // Input JSON size. 81 fAnimatorCount = 0; // Number of dynamically animated properties. 82 }; 83 84 /** 85 * Returns various animation build stats. 86 * 87 * @return Stats (see above). 88 */ getStats()89 const Stats& getStats() const { return fStats; } 90 91 /** 92 * Specify a loader for external resources (images, etc.). 93 */ 94 Builder& setResourceProvider(sk_sp<ResourceProvider>); 95 96 /** 97 * Specify a font manager for loading animation fonts. 98 */ 99 Builder& setFontManager(sk_sp<SkFontMgr>); 100 101 /** 102 * Specify a PropertyObserver to receive callbacks during parsing. 103 * 104 * See SkottieProperty.h for more details. 105 * 106 */ 107 Builder& setPropertyObserver(sk_sp<PropertyObserver>); 108 109 /** 110 * Register a Logger with this builder. 111 */ 112 Builder& setLogger(sk_sp<Logger>); 113 114 /** 115 * Register a MarkerObserver with this builder. 116 */ 117 Builder& setMarkerObserver(sk_sp<MarkerObserver>); 118 119 /** 120 * Animation factories. 121 */ 122 sk_sp<Animation> make(SkStream*); 123 sk_sp<Animation> make(const char* data, size_t length); 124 sk_sp<Animation> makeFromFile(const char path[]); 125 126 private: 127 const uint32_t fFlags; 128 129 sk_sp<ResourceProvider> fResourceProvider; 130 sk_sp<SkFontMgr> fFontMgr; 131 sk_sp<PropertyObserver> fPropertyObserver; 132 sk_sp<Logger> fLogger; 133 sk_sp<MarkerObserver> fMarkerObserver; 134 Stats fStats; 135 }; 136 137 /** 138 * Animation factories. 139 * 140 * Use the Builder helper above for more options/control. 141 */ 142 static sk_sp<Animation> Make(const char* data, size_t length); 143 static sk_sp<Animation> Make(SkStream*); 144 static sk_sp<Animation> MakeFromFile(const char path[]); 145 146 ~Animation(); 147 148 enum RenderFlag : uint32_t { 149 // When rendering into a known transparent buffer, clients can pass 150 // this flag to avoid some unnecessary compositing overhead for 151 // animations using layer blend modes. 152 kSkipTopLevelIsolation = 0x01, 153 }; 154 using RenderFlags = uint32_t; 155 156 /** 157 * Draws the current animation frame. 158 * 159 * It is undefined behavior to call render() on a newly created Animation 160 * before specifying an initial frame via one of the seek() variants. 161 * 162 * @param canvas destination canvas 163 * @param dst optional destination rect 164 * @param flags optional RenderFlags 165 */ 166 void render(SkCanvas* canvas, const SkRect* dst = nullptr) const; 167 void render(SkCanvas* canvas, const SkRect* dst, RenderFlags) const; 168 169 /** 170 * [Deprecated: use one of the other versions.] 171 * 172 * Updates the animation state for |t|. 173 * 174 * @param t normalized [0..1] frame selector (0 -> first frame, 1 -> final frame) 175 * @param ic optional invalidation controller (dirty region tracking) 176 * 177 */ 178 void seek(SkScalar t, sksg::InvalidationController* ic = nullptr) { 179 this->seekFrameTime(t * this->duration(), ic); 180 } 181 182 /** 183 * Update the animation state to match |t|, specified as a frame index 184 * i.e. relative to duration() * fps(). 185 * 186 * Fractional values are allowed and meaningful - e.g. 187 * 188 * 0.0 -> first frame 189 * 1.0 -> second frame 190 * 0.5 -> halfway between first and second frame 191 */ 192 void seekFrame(double t, sksg::InvalidationController* ic = nullptr); 193 194 /** Update the animation state to match t, specifed in frame time 195 * i.e. relative to duration(). 196 */ 197 void seekFrameTime(double t, sksg::InvalidationController* = nullptr); 198 199 /** 200 * Returns the animation duration in seconds. 201 */ duration()202 double duration() const { return fDuration; } 203 204 /** 205 * Returns the animation frame rate (frames / second). 206 */ fps()207 double fps() const { return fFPS; } 208 version()209 const SkString& version() const { return fVersion; } size()210 const SkSize& size() const { return fSize; } 211 212 private: 213 enum Flags : uint32_t { 214 kRequiresTopLevelIsolation = 1 << 0, // Needs to draw into a layer due to layer blending. 215 }; 216 217 Animation(std::unique_ptr<sksg::Scene>, SkString ver, const SkSize& size, 218 double inPoint, double outPoint, double duration, double fps, uint32_t flags); 219 220 std::unique_ptr<sksg::Scene> fScene; 221 const SkString fVersion; 222 const SkSize fSize; 223 const double fInPoint, 224 fOutPoint, 225 fDuration, 226 fFPS; 227 const uint32_t fFlags; 228 229 typedef SkNVRefCnt<Animation> INHERITED; 230 }; 231 232 } // namespace skottie 233 234 #endif // Skottie_DEFINED 235