1 /*
2  * Copyright (c) 2023 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 #ifndef USE_ROSEN_DRAWING
28 #include "core/components_ng/image_provider/adapter/skia_image_data.h"
29 #include "core/components_ng/render/adapter/pixelmap_image.h"
30 #include "core/components_ng/render/adapter/skia_image.h"
31 #else
32 #include "core/components_ng/image_provider/adapter/rosen/drawing_image_data.h"
33 #include "core/components_ng/render/adapter/pixelmap_image.h"
34 #include "core/components_ng/render/adapter/rosen/drawing_image.h"
35 #endif
36 
37 namespace OHOS::Ace::NG {
38 class AnimatedImage : public virtual CanvasImage {
39     DECLARE_ACE_TYPE(AnimatedImage, CanvasImage)
40 public:
41     // initialize animator
42     AnimatedImage(const std::unique_ptr<SkCodec>& codec, std::string url);
43     ~AnimatedImage() override;
44 
45     struct ResizeParam {
46         int32_t width = 0;
47         int32_t height = 0;
48         bool forceResize = false;
49         AIImageQuality imageQuality = AIImageQuality::NONE;
50     };
51 
GetResolutionQuality(AIImageQuality imageQuality)52     std::string GetResolutionQuality(AIImageQuality imageQuality)
53     {
54         switch (imageQuality) {
55             case AIImageQuality::NONE:
56                 return "LOW";
57             case AIImageQuality::NORMAL:
58                 return "MEDIUM";
59             case AIImageQuality::HIGH:
60                 return "HIGH";
61             default:
62                 return "LOW";
63         }
64     }
65 
66 #ifndef USE_ROSEN_DRAWING
67     static RefPtr<CanvasImage> Create(
68         const RefPtr<SkiaImageData>& data, const ResizeParam& size, const std::string& url);
69 #else
70     static RefPtr<CanvasImage> Create(
71         const RefPtr<DrawingImageData>& data, const ResizeParam& size, const std::string& url);
72 #endif
73     void ControlAnimation(bool play) override;
SetRedrawCallback(std::function<void ()> && callback)74     void SetRedrawCallback(std::function<void()>&& callback) override
75     {
76         redraw_ = std::move(callback);
77     }
78 
IsStatic()79     bool IsStatic() override
80     {
81         return false;
82     }
83 
GetCacheKey()84     const std::string& GetCacheKey() const
85     {
86         return cacheKey_;
87     }
88 
89     bool GetIsAnimating() const;
90 
91 protected:
92     // ensure frames decode serially
93     std::mutex decodeMtx_;
94     // protect currentFrame_
95     mutable std::mutex frameMtx_;
96 
97 private:
98     void RenderFrame(uint32_t idx);
99 
100     // runs on Background thread
101     void DecodeFrame(uint32_t idx);
102     bool GetCachedFrame(uint32_t idx);
103 
104     virtual void DecodeImpl(uint32_t idx) = 0;
105     virtual RefPtr<CanvasImage> GetCachedFrameImpl(const std::string& key) = 0;
106     virtual void UseCachedFrame(RefPtr<CanvasImage>&& image) = 0;
107     virtual void CacheFrame(const std::string& key) = 0;
108 
109     std::atomic_int32_t queueSize_ = 0;
110     RefPtr<Animator> animator_;
111     std::function<void()> redraw_;
112     const std::string cacheKey_;
113     bool animationState_ = false;
114 
115     ACE_DISALLOW_COPY_AND_MOVE(AnimatedImage);
116 };
117 
118 // ================================================================================================
119 
120 #ifndef USE_ROSEN_DRAWING
121 class AnimatedSkImage : public AnimatedImage, public SkiaImage {
DECLARE_ACE_TYPE(AnimatedSkImage,AnimatedImage,SkiaImage)122     DECLARE_ACE_TYPE(AnimatedSkImage, AnimatedImage, SkiaImage)
123 public:
124     AnimatedSkImage(std::unique_ptr<SkCodec> codec, std::string url)
125         : AnimatedImage(codec, std::move(url)), codec_(std::move(codec))
126     {}
127     ~AnimatedSkImage() override = default;
128 
129     sk_sp<SkImage> GetImage() const override;
130 #else
131 class AnimatedRSImage : public AnimatedImage, public DrawingImage {
132     DECLARE_ACE_TYPE(AnimatedRSImage, AnimatedImage, DrawingImage)
133 public:
134     AnimatedRSImage(std::unique_ptr<SkCodec> codec, std::string url)
135         : AnimatedImage(codec, std::move(url)), codec_(std::move(codec))
136     {}
137     ~AnimatedRSImage() override = default;
138 
139     std::shared_ptr<RSImage> GetImage() const override;
140 
141     int32_t GetWidth() const override
142     {
143         return currentFrame_ ? currentFrame_->GetWidth() : 0;
144     }
145 
146     int32_t GetHeight() const override
147     {
148         return currentFrame_ ? currentFrame_->GetHeight() : 0;
149     }
150 #endif
151 
Clone()152     RefPtr<CanvasImage> Clone() override
153     {
154         return Claim(this);
155     }
156 
157 private:
158     void DecodeImpl(uint32_t idx) override;
159 
160     void CacheFrame(const std::string& key) override;
161     RefPtr<CanvasImage> GetCachedFrameImpl(const std::string& key) override;
162     void UseCachedFrame(RefPtr<CanvasImage>&& image) override;
163 
164 #ifndef USE_ROSEN_DRAWING
165     SkBitmap requiredFrame_;
166     std::unique_ptr<SkCodec> codec_;
167     sk_sp<SkImage> currentFrame_;
168 
169     ACE_DISALLOW_COPY_AND_MOVE(AnimatedSkImage);
170 #else
171     RSBitmap requiredFrame_;
172     std::unique_ptr<SkCodec> codec_;
173     std::shared_ptr<RSImage> currentFrame_;
174 
175     ACE_DISALLOW_COPY_AND_MOVE(AnimatedRSImage);
176 #endif
177 };
178 
179 // ================================================================================================
180 
181 class AnimatedPixmap : public AnimatedImage, public PixelMapImage {
182     DECLARE_ACE_TYPE(AnimatedPixmap, AnimatedImage, PixelMapImage)
183 public:
184     AnimatedPixmap(const std::unique_ptr<SkCodec>& codec, const RefPtr<ImageSource>& src, const ResizeParam& size,
185         std::string url);
186     ~AnimatedPixmap() override = default;
187     RefPtr<PixelMap> GetPixelMap() const override;
188 
Clone()189     RefPtr<CanvasImage> Clone() override
190     {
191         return Claim(this);
192     }
193 
194 private:
195     void DecodeImpl(uint32_t idx) override;
196 
197     void CacheFrame(const std::string& key) override;
198     RefPtr<CanvasImage> GetCachedFrameImpl(const std::string& key) override;
199     void UseCachedFrame(RefPtr<CanvasImage>&& image) override;
200 
201     RefPtr<PixelMap> currentFrame_;
202     bool intrSizeInitial_ = true;
203 
204     ResizeParam size_;
205     const RefPtr<ImageSource> src_;
206 
207     ACE_DISALLOW_COPY_AND_MOVE(AnimatedPixmap);
208 };
209 } // namespace OHOS::Ace::NG
210 
211 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_ADAPTER_ANIMATED_IMAGE_H
212