1 /*
2  * Copyright (c) 2022-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 #include "image_object.h"
17 
18 #ifdef USE_ROSEN_DRAWING
19 #include "drawing/engine_adapter/skia_adapter/skia_data.h"
20 #endif
21 
22 namespace OHOS::Ace {
23 class AnimatedImageObject : public ImageObject {
24     DECLARE_ACE_TYPE(AnimatedImageObject, ImageObject);
25 public:
26 #ifndef USE_ROSEN_DRAWING
AnimatedImageObject(ImageSourceInfo source,const Size & imageSize,int32_t frameCount,const sk_sp<SkData> & data)27     AnimatedImageObject(
28         ImageSourceInfo source,
29         const Size& imageSize,
30         int32_t frameCount,
31         const sk_sp<SkData>& data)
32         : ImageObject(source, imageSize, frameCount), skData_(data)
33     {}
34 #else
35     AnimatedImageObject(
36         ImageSourceInfo source,
37         const Size& imageSize,
38         int32_t frameCount,
39         const std::shared_ptr<RSData>& data)
40         : ImageObject(source, imageSize, frameCount), drawingData_(data)
41     {}
42 #endif
43 
44     ~AnimatedImageObject() override = default;
45 
46     void UploadToGpuForRender(
47         const WeakPtr<PipelineBase>& context,
48         const UploadSuccessCallback& successCallback,
49         const FailedCallback& failedCallback,
50         const Size& imageSize,
51         bool forceResize,
52         bool syncMode = false) override;
53 
Pause()54     void Pause() override
55     {
56         if (animatedPlayer_) {
57             LOGI("animatied image Paused");
58             animatedPlayer_->Pause();
59         }
60     }
61 
Resume()62     void Resume() override
63     {
64         if (animatedPlayer_) {
65             LOGI("animatied image Resume");
66             animatedPlayer_->Resume();
67         }
68     }
69 
ClearData()70     void ClearData() override
71     {
72 #ifndef USE_ROSEN_DRAWING
73         skData_ = nullptr;
74 #else
75         drawingData_ = nullptr;
76 #endif
77     }
78 
Clone()79     RefPtr<ImageObject> Clone() override
80     {
81 #ifndef USE_ROSEN_DRAWING
82         return MakeRefPtr<AnimatedImageObject>(imageSource_, imageSize_, frameCount_, skData_);
83 #else
84         return MakeRefPtr<AnimatedImageObject>(imageSource_, imageSize_, frameCount_, drawingData_);
85 #endif
86     }
87 
88 private:
89 #ifndef USE_ROSEN_DRAWING
90     sk_sp<SkData> skData_;
91 #else
92     std::shared_ptr<RSData> drawingData_;
93 #endif
94     RefPtr<AnimatedImagePlayer> animatedPlayer_;
95 };
96 
UploadToGpuForRender(const WeakPtr<PipelineBase> & context,const UploadSuccessCallback & successCallback,const FailedCallback & failedCallback,const Size & imageSize,bool forceResize,bool syncMode)97 void AnimatedImageObject::UploadToGpuForRender(
98     const WeakPtr<PipelineBase>& context,
99     const UploadSuccessCallback& successCallback,
100     const FailedCallback& failedCallback,
101     const Size& imageSize,
102     bool forceResize,
103     bool syncMode)
104 {
105     constexpr float SizeOffset = 0.5f;
106 #ifndef USE_ROSEN_DRAWING
107     if (!animatedPlayer_ && skData_) {
108         auto codec = SkCodec::MakeFromData(skData_);
109 #else
110     if (!animatedPlayer_ && drawingData_) {
111         auto skData = SkData::MakeWithoutCopy(drawingData_->GetData(), drawingData_->GetSize());
112         auto codec = SkCodec::MakeFromData(skData);
113 #endif
114         int32_t dstWidth = -1;
115         int32_t dstHeight = -1;
116         if (forceResize) {
117             dstWidth = static_cast<int32_t>(imageSize.Width() + SizeOffset);
118             dstHeight = static_cast<int32_t>(imageSize.Height() + SizeOffset);
119         }
120         animatedPlayer_ = MakeRefPtr<AnimatedImagePlayer>(
121             imageSource_,
122             successCallback,
123             context,
124             std::move(codec),
125             dstWidth,
126             dstHeight);
127         ClearData();
128     } else if (animatedPlayer_ && forceResize && imageSize.IsValid()) {
129         LOGI("animated player has been constructed, forceResize: %{public}s", imageSize.ToString().c_str());
130         int32_t dstWidth = static_cast<int32_t>(imageSize.Width() + SizeOffset);
131         int32_t dstHeight = static_cast<int32_t>(imageSize.Height() + SizeOffset);
132         animatedPlayer_->SetTargetSize(dstWidth, dstHeight);
133 #ifndef USE_ROSEN_DRAWING
134     } else if (!animatedPlayer_ && !skData_) {
135 #else
136     } else if (!animatedPlayer_ && !drawingData_) {
137 #endif
138         LOGE("animated player is not constructed and image data is null, can not construct animated player!");
139     } else if (animatedPlayer_ && !forceResize) {
140         LOGI("animated player has been constructed, do nothing!");
141     }
142 }
143 
144 #ifndef USE_ROSEN_DRAWING
145 RefPtr<ImageObject> CreateAnimatedImageObject(ImageSourceInfo source, const Size& imageSize, int32_t frameCount,
146     const sk_sp<SkData>& data)
147 #else
148 RefPtr<ImageObject> CreateAnimatedImageObject(ImageSourceInfo source, const Size& imageSize, int32_t frameCount,
149     const std::shared_ptr<RSData>& data)
150 #endif
151 {
152     return Referenced::MakeRefPtr<AnimatedImageObject>(source, imageSize, frameCount, data);
153 }
154 }