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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_IMAGE_PROVIDER_IMAGE_LOADING_CONTEXT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_IMAGE_PROVIDER_IMAGE_LOADING_CONTEXT_H 18 19 #include <cstdint> 20 21 #include "base/geometry/ng/size_t.h" 22 #include "base/image/pixel_map.h" 23 #include "base/thread/task_executor.h" 24 #include "core/components/common/layout/constants.h" 25 #include "core/components_ng/image_provider/image_object.h" 26 #include "core/components_ng/image_provider/image_provider.h" 27 #include "core/components_ng/image_provider/image_state_manager.h" 28 #include "core/components_ng/pattern/image/image_dfx.h" 29 30 namespace OHOS::Ace::NG { 31 32 using PendingMakeCanvasImageTask = std::function<void()>; 33 // [ImageLoadingContext] do two things: 34 // 1. Provide interfaces for who owns it, notify it's owner when loading events come. 35 // 2. Drive [ImageObject] to load and make [CanvasImage]. 36 class ACE_FORCE_EXPORT ImageLoadingContext : public AceType { 37 DECLARE_ACE_TYPE(ImageLoadingContext, AceType); 38 39 public: 40 // Create an empty ImageObject and initialize state machine when the constructor is called 41 ImageLoadingContext(const ImageSourceInfo& src, LoadNotifier&& loadNotifier, bool syncLoad = false, 42 const ImageDfxConfig& imageDfxConfig = {}); 43 ~ImageLoadingContext() override; 44 45 // return true if calling MakeCanvasImage is necessary 46 bool MakeCanvasImageIfNeed(const SizeF& dstSize, bool autoResize, ImageFit imageFit, 47 const std::optional<SizeF>& sourceSize = std::nullopt, bool hasValidSlice = false); 48 49 /* interfaces to drive image loading */ 50 void LoadImageData(); 51 void MakeCanvasImage(const SizeF& dstSize, bool needResize, ImageFit imageFit = ImageFit::COVER, 52 const std::optional<SizeF>& sourceSize = std::nullopt); 53 void ResetLoading(); 54 void ResumeLoading(); 55 56 /* interfaces to get properties */ 57 SizeF GetImageSize() const; 58 SizeF GetOriginImageSize() const; 59 const RectF& GetDstRect() const; 60 const RectF& GetSrcRect() const; 61 ImageFit GetImageFit() const; 62 int32_t GetFrameCount() const; 63 64 RefPtr<CanvasImage> MoveCanvasImage(); 65 RefPtr<ImageObject> MoveImageObject(); GetImageObject()66 RefPtr<ImageObject> GetImageObject() 67 { 68 return imageObj_; 69 } 70 71 const ImageSourceInfo& GetSourceInfo() const; 72 const SizeF& GetDstSize() const; 73 bool GetAutoResize() const; 74 std::optional<SizeF> GetSourceSize() const; 75 bool NeedAlt() const; 76 77 /* interfaces to set properties */ 78 void SetImageFit(ImageFit imageFit); 79 void SetAutoResize(bool needResize); 80 void SetSourceSize(const std::optional<SizeF>& sourceSize = std::nullopt); GetSrc()81 const ImageSourceInfo GetSrc() const 82 { 83 return src_; 84 } 85 GetStateManger()86 const RefPtr<ImageStateManager>& GetStateManger() 87 { 88 return stateManager_; 89 } 90 91 // callbacks that will be called by ImageProvider when load process finishes 92 void DataReadyCallback(const RefPtr<ImageObject>& imageObj); 93 void SuccessCallback(const RefPtr<CanvasImage>& canvasImage); 94 void FailCallback(const std::string& errorMsg); 95 const std::string GetCurrentLoadingState(); 96 void ResizableCalcDstSize(); 97 bool Downloadable(); 98 void OnDataReady(); 99 100 // Needed to restore the relevant containerId from the originating thread GetContainerId()101 int32_t GetContainerId() const 102 { 103 return containerId_; 104 } 105 SetIsHdrDecoderNeed(bool isHdrDecoderNeed)106 void SetIsHdrDecoderNeed(bool isHdrDecoderNeed) 107 { 108 isHdrDecoderNeed_ = isHdrDecoderNeed; 109 } 110 GetIsHdrDecoderNeed()111 bool GetIsHdrDecoderNeed() 112 { 113 return isHdrDecoderNeed_; 114 } 115 SetImageQuality(AIImageQuality imageQuality)116 void SetImageQuality(AIImageQuality imageQuality) 117 { 118 imageQuality_ = imageQuality; 119 } 120 GetImageQuality()121 AIImageQuality GetImageQuality() 122 { 123 return imageQuality_; 124 } 125 SetPhotoDecodeFormat(PixelFormat photoDecodeFormat)126 void SetPhotoDecodeFormat(PixelFormat photoDecodeFormat) 127 { 128 photoDecodeFormat_ = photoDecodeFormat; 129 } 130 GetPhotoDecodeFormat()131 PixelFormat GetPhotoDecodeFormat() 132 { 133 return photoDecodeFormat_; 134 } 135 FinishMearuse()136 void FinishMearuse() 137 { 138 measureFinish_ = true; 139 } 140 141 void CallbackAfterMeasureIfNeed(); 142 143 void OnDataReadyOnCompleteCallBack(); 144 void SetOnProgressCallback(std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)>&& onProgress); GetErrorMsg()145 const std::string& GetErrorMsg() 146 { 147 return errorMsg_; 148 } 149 SetImageDfxConfig(const ImageDfxConfig & imageDfxConfig)150 void SetImageDfxConfig(const ImageDfxConfig& imageDfxConfig) 151 { 152 imageDfxConfig_ = imageDfxConfig; 153 } 154 155 GetImageDfxConfig()156 const ImageDfxConfig& GetImageDfxConfig() 157 { 158 return imageDfxConfig_; 159 } 160 161 void DownloadOnProgress(const uint32_t& dlNow, const uint32_t& dlTotal); 162 GetOnProgressCallback()163 std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)> GetOnProgressCallback() 164 { 165 return onProgressCallback_; 166 } 167 168 private: 169 #define DEFINE_SET_NOTIFY_TASK(loadResult) \ 170 void Set##loadResult##NotifyTask(loadResult##NotifyTask&& loadResult##NotifyTask) \ 171 { \ 172 notifiers_.on##loadResult##_ = std::move(loadResult##NotifyTask); \ 173 } 174 175 // classes that use [ImageLoadingContext] can register three notify tasks to do things 176 DEFINE_SET_NOTIFY_TASK(DataReady); 177 DEFINE_SET_NOTIFY_TASK(LoadSuccess); 178 DEFINE_SET_NOTIFY_TASK(LoadFail); 179 180 // tasks that run when entering a new state 181 void OnUnloaded(); 182 void OnDataLoading(); 183 void OnMakeCanvasImage(); 184 void OnLoadSuccess(); 185 void OnLoadFail(); 186 // round up int to the nearest 2-fold proportion of image width 187 // REQUIRE: value > 0, image width > 0 188 int32_t RoundUp(int32_t value); 189 static SizeF CalculateTargetSize(const SizeF& srcSize, const SizeF& dstSize, const SizeF& rawImageSize); 190 SizeChanging(const SizeF & dstSize)191 inline bool SizeChanging(const SizeF& dstSize) 192 { 193 return dstSize_.IsPositive() && dstSize != dstSize_; 194 } 195 196 ImageSourceInfo src_; 197 RefPtr<ImageStateManager> stateManager_; 198 RefPtr<ImageObject> imageObj_; 199 RefPtr<CanvasImage> canvasImage_; 200 201 // [LoadNotifier] contains 3 tasks to notify whom uses [ImageLoadingContext] of loading results 202 LoadNotifier notifiers_; 203 204 // the container of the creator thread of this image loading context 205 const int32_t containerId_ {0}; 206 207 bool isHdrDecoderNeed_ = false; 208 PixelFormat photoDecodeFormat_ = PixelFormat::UNKNOWN; 209 bool autoResize_ = true; 210 bool syncLoad_ = false; 211 212 AIImageQuality imageQuality_ = AIImageQuality::NONE; 213 214 RectF srcRect_; 215 RectF dstRect_; 216 SizeF dstSize_; 217 std::atomic<bool> measureFinish_ = false; 218 std::atomic<bool> needErrorCallBack_ = false; 219 std::atomic<bool> needDataReadyCallBack_ = false; 220 // to determine whether the image needs to be reloaded 221 int32_t sizeLevel_ = -1; 222 ImageDfxConfig imageDfxConfig_; 223 224 ImageFit imageFit_ = ImageFit::COVER; 225 std::unique_ptr<SizeF> sourceSizePtr_ = nullptr; 226 std::function<void()> updateParamsCallback_ = nullptr; 227 228 std::string errorMsg_; 229 // to cancel MakeCanvasImage task 230 std::string canvasKey_; 231 232 bool firstLoadImage_ = true; 233 234 // if another makeCanvasImage task arrives and current state cannot handle makeCanvasImage command, 235 // save the least recent makeCanvasImage task and trigger it when the previous makeCanvasImage task end 236 // and state becomes MAKE_CANVAS_IMAGE_SUCCESS 237 PendingMakeCanvasImageTask pendingMakeCanvasImageTask_ = nullptr; 238 239 friend class ImageStateManager; 240 ACE_DISALLOW_COPY_AND_MOVE(ImageLoadingContext); 241 242 std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)> onProgressCallback_ = nullptr; 243 }; 244 245 } // namespace OHOS::Ace::NG 246 247 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_IMAGE_PROVIDER_IMAGE_LOADING_CONTEXT_H 248