1 /* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_ANIMATED_IMAGE_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_ANIMATED_IMAGE_H 18 19 #include <atomic> 20 #include <memory> 21 #include <utility> 22 23 #include "include/codec/SkCodec.h" 24 #include "include/core/SkImage.h" 25 26 #include "base/image/image_source.h" 27 #include "base/thread/cancelable_callback.h" 28 #ifndef USE_ROSEN_DRAWING 29 #include "core/components_ng/image_provider/adapter/skia_image_data.h" 30 #include "core/components_ng/render/adapter/pixelmap_image.h" 31 #include "core/components_ng/render/adapter/skia_image.h" 32 #else 33 #include "core/components_ng/image_provider/adapter/rosen/drawing_image_data.h" 34 #include "core/components_ng/render/adapter/pixelmap_image.h" 35 #include "core/components_ng/render/adapter/rosen/drawing_image.h" 36 #endif 37 38 namespace OHOS::Ace { 39 class Animator; 40 } 41 42 namespace OHOS::Ace::NG { 43 class AnimatedImage : public virtual CanvasImage { 44 DECLARE_ACE_TYPE(AnimatedImage, CanvasImage) 45 public: 46 // initialize animator 47 AnimatedImage(const std::unique_ptr<SkCodec>& codec, std::string url); 48 ~AnimatedImage() override; 49 50 struct ResizeParam { 51 int32_t width = 0; 52 int32_t height = 0; 53 bool forceResize = false; 54 AIImageQuality imageQuality = AIImageQuality::NONE; 55 }; 56 57 #ifndef USE_ROSEN_DRAWING 58 static RefPtr<CanvasImage> Create( 59 const RefPtr<SkiaImageData>& data, const ResizeParam& size, const std::string& url); 60 #else 61 static RefPtr<CanvasImage> Create( 62 const RefPtr<DrawingImageData>& data, const ResizeParam& size, const std::string& url); 63 #endif 64 void ControlAnimation(bool play) override; SetRedrawCallback(std::function<void ()> && callback)65 void SetRedrawCallback(std::function<void()>&& callback) override 66 { 67 redraw_ = std::move(callback); 68 } 69 IsStatic()70 bool IsStatic() override 71 { 72 return false; 73 } 74 GetCacheKey()75 const std::string& GetCacheKey() const 76 { 77 return cacheKey_; 78 } 79 80 bool GetIsAnimating() const; 81 82 protected: 83 // ensure frames decode serially 84 std::mutex decodeMtx_; 85 // protect currentFrame_ 86 mutable std::mutex frameMtx_; 87 88 private: 89 void RenderFrame(uint32_t idx); 90 91 // runs on Background thread 92 void DecodeFrame(uint32_t idx); 93 bool GetCachedFrame(uint32_t idx); 94 95 // git animation control 96 static int GenerateIteration(const std::unique_ptr<SkCodec>& codec); 97 static std::vector<int> GenerateDuration(const std::unique_ptr<SkCodec>& codec); 98 void PostPlayTask(uint32_t idx, int iteration); 99 100 virtual void DecodeImpl(uint32_t idx) = 0; GetCachedFrameImpl(const std::string & key)101 virtual RefPtr<CanvasImage> GetCachedFrameImpl(const std::string& key) 102 { 103 return nullptr; 104 } 105 virtual void UseCachedFrame(RefPtr<CanvasImage>&& image) = 0; 106 virtual void CacheFrame(const std::string& key) = 0; 107 108 CancelableCallback<void()> currentTask_; 109 const std::string cacheKey_; 110 std::vector<int> duration_; 111 std::atomic_int32_t queueSize_ = 0; 112 std::function<void()> redraw_; 113 int iteration_ = 0; 114 uint32_t currentIdx_ = 0; 115 bool animationState_ = false; 116 117 ACE_DISALLOW_COPY_AND_MOVE(AnimatedImage); 118 }; 119 120 // ================================================================================================ 121 122 #ifndef USE_ROSEN_DRAWING 123 class AnimatedSkImage : public AnimatedImage, public SkiaImage { DECLARE_ACE_TYPE(AnimatedSkImage,AnimatedImage,SkiaImage)124 DECLARE_ACE_TYPE(AnimatedSkImage, AnimatedImage, SkiaImage) 125 public: 126 AnimatedSkImage(std::unique_ptr<SkCodec> codec, std::string url) 127 : AnimatedImage(codec, std::move(url)), codec_(std::move(codec)) 128 {} 129 ~AnimatedSkImage() override = default; 130 131 sk_sp<SkImage> GetImage() const override; 132 #else 133 class AnimatedRSImage : public AnimatedImage, public DrawingImage { 134 DECLARE_ACE_TYPE(AnimatedRSImage, AnimatedImage, DrawingImage) 135 public: 136 AnimatedRSImage(std::unique_ptr<SkCodec> codec, std::string url) 137 : AnimatedImage(codec, std::move(url)), codec_(std::move(codec)) 138 {} 139 ~AnimatedRSImage() override = default; 140 141 std::shared_ptr<RSImage> GetImage() const override; 142 143 int32_t GetWidth() const override 144 { 145 return currentFrame_ ? currentFrame_->GetWidth() : 0; 146 } 147 148 int32_t GetHeight() const override 149 { 150 return currentFrame_ ? currentFrame_->GetHeight() : 0; 151 } 152 #endif 153 Clone()154 RefPtr<CanvasImage> Clone() override 155 { 156 return Claim(this); 157 } 158 159 private: 160 void DecodeImpl(uint32_t idx) override; 161 162 void CacheFrame(const std::string& key) override; 163 RefPtr<CanvasImage> GetCachedFrameImpl(const std::string& key) override; 164 void UseCachedFrame(RefPtr<CanvasImage>&& image) override; 165 166 #ifndef USE_ROSEN_DRAWING 167 SkBitmap requiredFrame_; 168 std::unique_ptr<SkCodec> codec_; 169 sk_sp<SkImage> currentFrame_; 170 171 ACE_DISALLOW_COPY_AND_MOVE(AnimatedSkImage); 172 #else 173 RSBitmap requiredFrame_; 174 std::unique_ptr<SkCodec> codec_; 175 std::shared_ptr<RSImage> currentFrame_; 176 177 ACE_DISALLOW_COPY_AND_MOVE(AnimatedRSImage); 178 #endif 179 }; 180 181 // ================================================================================================ 182 183 class AnimatedPixmap : public AnimatedImage, public PixelMapImage { 184 DECLARE_ACE_TYPE(AnimatedPixmap, AnimatedImage, PixelMapImage) 185 public: 186 AnimatedPixmap(const std::unique_ptr<SkCodec>& codec, const RefPtr<ImageSource>& src, const ResizeParam& size, 187 std::string url); 188 ~AnimatedPixmap() override = default; 189 RefPtr<PixelMap> GetPixelMap() const override; 190 Clone()191 RefPtr<CanvasImage> Clone() override 192 { 193 return Claim(this); 194 } 195 196 private: 197 void DecodeImpl(uint32_t idx) override; 198 199 void CacheFrame(const std::string& key) override; 200 RefPtr<CanvasImage> GetCachedFrameImpl(const std::string& key) override; 201 void UseCachedFrame(RefPtr<CanvasImage>&& image) override; 202 203 RefPtr<PixelMap> currentFrame_; 204 bool intrSizeInitial_ = true; 205 206 ResizeParam size_; 207 const RefPtr<ImageSource> src_; 208 209 ACE_DISALLOW_COPY_AND_MOVE(AnimatedPixmap); 210 }; 211 } // namespace OHOS::Ace::NG 212 213 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_ANIMATED_IMAGE_H 214