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 bool isSceneBoardWindow = false, 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 std::string GetImageSizeInfo() const; 60 const RectF& GetDstRect() const; 61 const RectF& GetSrcRect() const; 62 ImageFit GetImageFit() const; 63 int32_t GetFrameCount() const; 64 65 RefPtr<CanvasImage> MoveCanvasImage(); 66 RefPtr<ImageObject> MoveImageObject(); GetImageObject()67 RefPtr<ImageObject> GetImageObject() 68 { 69 return imageObj_; 70 } 71 72 const ImageSourceInfo& GetSourceInfo() const; 73 const SizeF& GetDstSize() const; 74 bool GetAutoResize() const; 75 std::optional<SizeF> GetSourceSize() const; 76 bool NeedAlt() const; 77 78 /* interfaces to set properties */ 79 void SetImageFit(ImageFit imageFit); 80 void SetAutoResize(bool needResize); 81 void SetSourceSize(const std::optional<SizeF>& sourceSize = std::nullopt); GetSrc()82 const ImageSourceInfo GetSrc() const 83 { 84 return src_; 85 } 86 GetStateManger()87 const RefPtr<ImageStateManager>& GetStateManger() 88 { 89 return stateManager_; 90 } 91 92 // callbacks that will be called by ImageProvider when load process finishes 93 void DataReadyCallback(const RefPtr<ImageObject>& imageObj); 94 void SuccessCallback(const RefPtr<CanvasImage>& canvasImage); 95 void FailCallback(const std::string& errorMsg, const ImageErrorInfo& errorInfo = {}); 96 const std::string GetCurrentLoadingState(); 97 void ResizableCalcDstSize(); 98 bool Downloadable(); 99 void OnDataReady(); 100 101 // Needed to restore the relevant containerId from the originating thread GetContainerId()102 int32_t GetContainerId() const 103 { 104 return containerId_; 105 } 106 SetIsHdrDecoderNeed(bool isHdrDecoderNeed)107 void SetIsHdrDecoderNeed(bool isHdrDecoderNeed) 108 { 109 isHdrDecoderNeed_ = isHdrDecoderNeed; 110 } 111 GetIsHdrDecoderNeed()112 bool GetIsHdrDecoderNeed() 113 { 114 return isHdrDecoderNeed_; 115 } 116 SetImageQuality(AIImageQuality imageQuality)117 void SetImageQuality(AIImageQuality imageQuality) 118 { 119 imageQuality_ = imageQuality; 120 } 121 GetImageQuality()122 AIImageQuality GetImageQuality() 123 { 124 return imageQuality_; 125 } 126 SetPhotoDecodeFormat(PixelFormat photoDecodeFormat)127 void SetPhotoDecodeFormat(PixelFormat photoDecodeFormat) 128 { 129 photoDecodeFormat_ = photoDecodeFormat; 130 } 131 GetPhotoDecodeFormat()132 PixelFormat GetPhotoDecodeFormat() 133 { 134 return photoDecodeFormat_; 135 } 136 FinishMeasure()137 void FinishMeasure() 138 { 139 measureFinish_ = true; 140 } 141 142 void CallbackAfterMeasureIfNeed(); 143 144 void OnDataReadyOnCompleteCallBack(); 145 void SetOnProgressCallback(std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)>&& onProgress); GetErrorMsg()146 const std::string& GetErrorMsg() 147 { 148 return errorMsg_; 149 } 150 SetImageDfxConfig(const ImageDfxConfig & imageDfxConfig)151 void SetImageDfxConfig(const ImageDfxConfig& imageDfxConfig) 152 { 153 imageDfxConfig_ = imageDfxConfig; 154 } 155 156 GetImageDfxConfig()157 const ImageDfxConfig& GetImageDfxConfig() 158 { 159 return imageDfxConfig_; 160 } 161 162 void DownloadOnProgress(const uint32_t& dlNow, const uint32_t& dlTotal); 163 GetOnProgressCallback()164 std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)> GetOnProgressCallback() 165 { 166 return onProgressCallback_; 167 } 168 169 private: 170 #define DEFINE_SET_NOTIFY_TASK(loadResult) \ 171 void Set##loadResult##NotifyTask(loadResult##NotifyTask&& loadResult##NotifyTask) \ 172 { \ 173 notifiers_.on##loadResult##_ = std::move(loadResult##NotifyTask); \ 174 } 175 176 // classes that use [ImageLoadingContext] can register three notify tasks to do things 177 DEFINE_SET_NOTIFY_TASK(DataReady); 178 DEFINE_SET_NOTIFY_TASK(LoadSuccess); 179 DEFINE_SET_NOTIFY_TASK(LoadFail); 180 181 // tasks that run when entering a new state 182 void OnUnloaded(); 183 void OnDataLoading(); 184 void OnMakeCanvasImage(); 185 void OnLoadSuccess(); 186 void OnLoadFail(); 187 // round up int to the nearest 2-fold proportion of image width 188 // REQUIRE: value > 0, image width > 0 189 int32_t RoundUp(int32_t value); 190 static SizeF CalculateTargetSize(const SizeF& srcSize, const SizeF& dstSize, const SizeF& rawImageSize); 191 SizeChanging(const SizeF & dstSize)192 inline bool SizeChanging(const SizeF& dstSize) 193 { 194 return dstSize_.IsPositive() && dstSize != dstSize_; 195 } 196 197 ImageSourceInfo src_; 198 RefPtr<ImageStateManager> stateManager_; 199 RefPtr<ImageObject> imageObj_; 200 RefPtr<CanvasImage> canvasImage_; 201 202 // [LoadNotifier] contains 3 tasks to notify whom uses [ImageLoadingContext] of loading results 203 LoadNotifier notifiers_; 204 205 // the container of the creator thread of this image loading context 206 const int32_t containerId_ {0}; 207 208 bool isHdrDecoderNeed_ = false; 209 PixelFormat photoDecodeFormat_ = PixelFormat::UNKNOWN; 210 bool autoResize_ = true; 211 bool syncLoad_ = false; 212 bool isSceneBoardWindow_ = false; 213 214 AIImageQuality imageQuality_ = AIImageQuality::NONE; 215 216 RectF srcRect_; 217 RectF dstRect_; 218 SizeF dstSize_; 219 std::atomic<bool> measureFinish_ = false; 220 std::atomic<bool> needErrorCallBack_ = false; 221 std::atomic<bool> needDataReadyCallBack_ = false; 222 // to determine whether the image needs to be reloaded 223 int32_t sizeLevel_ = -1; 224 ImageDfxConfig imageDfxConfig_; 225 226 ImageFit imageFit_ = ImageFit::COVER; 227 std::unique_ptr<SizeF> sourceSizePtr_ = nullptr; 228 std::function<void()> updateParamsCallback_ = nullptr; 229 230 std::string errorMsg_; 231 ImageErrorInfo errorInfo_; 232 // to cancel MakeCanvasImage task 233 std::string canvasKey_; 234 235 bool firstLoadImage_ = true; 236 237 // if another makeCanvasImage task arrives and current state cannot handle makeCanvasImage command, 238 // save the least recent makeCanvasImage task and trigger it when the previous makeCanvasImage task end 239 // and state becomes MAKE_CANVAS_IMAGE_SUCCESS 240 PendingMakeCanvasImageTask pendingMakeCanvasImageTask_ = nullptr; 241 242 friend class ImageStateManager; 243 ACE_DISALLOW_COPY_AND_MOVE(ImageLoadingContext); 244 245 std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)> onProgressCallback_ = nullptr; 246 }; 247 248 } // namespace OHOS::Ace::NG 249 250 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_IMAGE_PROVIDER_IMAGE_LOADING_CONTEXT_H 251