diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponse.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponse.h index 4f56688b082..2e6ab4455db 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponse.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponse.h @@ -21,6 +21,7 @@ class ImageResponse final { Completed, Failed, Cancelled, + Consumed, }; ImageResponse(std::shared_ptr image, std::shared_ptr metadata); diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.cpp b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.cpp index 5b3e2574a9f..bbe23fa9565 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.cpp +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace facebook::react { @@ -31,6 +32,7 @@ void ImageResponseObserverCoordinator::addObserver( case ImageResponse::Status::Completed: { auto imageData = imageData_; auto imageMetadata = imageMetadata_; + consumeResponse(); mutex_.unlock(); observer.didReceiveImage(ImageResponse{imageData, imageMetadata}); break; @@ -41,7 +43,8 @@ void ImageResponseObserverCoordinator::addObserver( observer.didReceiveFailure(ImageLoadError{imageErrorData}); break; } - case ImageResponse::Status::Cancelled: { + case ImageResponse::Status::Cancelled: + case ImageResponse::Status::Consumed: { observers_.push_back(&observer); status_ = ImageResponse::Status::Loading; mutex_.unlock(); @@ -93,6 +96,9 @@ void ImageResponseObserverCoordinator::nativeImageResponseComplete( status_ == ImageResponse::Status::Cancelled); status_ = ImageResponse::Status::Completed; auto observers = observers_; + if (!observers.empty()) { + consumeResponse(); + } mutex_.unlock(); for (auto observer : observers) { @@ -116,4 +122,12 @@ void ImageResponseObserverCoordinator::nativeImageResponseFailed( } } +void ImageResponseObserverCoordinator::consumeResponse() const { + if (ReactNativeFeatureFlags::releaseImageDataWhenConsumed()) { + status_ = ImageResponse::Status::Consumed; + imageData_.reset(); + imageMetadata_.reset(); + } +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h index 3aae8ee9ab6..f70ac494707 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h @@ -61,6 +61,11 @@ class ImageResponseObserverCoordinator { void nativeImageResponseFailed(const ImageLoadError& loadError) const; private: + /* + * Resets the cached image data pointers. Needs to be protected by mutex_. + */ + void consumeResponse() const; + /* * List of observers. * Mutable: protected by mutex_.