diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp index 8e350f31e0a031..3b2be76a229812 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -641,6 +642,19 @@ void FabricUIManagerBinding::schedulerShouldRenderTransactions( if (!mountingManager) { return; } + + if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) { + auto weakImageFetcher = + scheduler_->getContextContainer()->find>( + ImageFetcherKey); + auto imageFetcher = weakImageFetcher.has_value() + ? weakImageFetcher.value().lock() + : nullptr; + if (imageFetcher != nullptr) { + imageFetcher->flushImageRequests(); + } + } + if (ReactNativeFeatureFlags::enableAccumulatedUpdatesInRawPropsAndroid()) { auto mountingTransaction = mountingCoordinator->pullTransaction( /* willPerformAsynchronously = */ true); diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageManager.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageManager.h index 61c90c4efd3a8f..88b58c6313a4f1 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageManager.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/ImageManager.h @@ -37,6 +37,9 @@ class ImageManager { Tag tag = {}) const; private: +#ifdef ANDROID + std::shared_ptr contextContainer_{}; +#endif void *self_{}; }; diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp index 7d7830369211d4..b67f2c29266ca8 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp @@ -8,10 +8,13 @@ #include "ImageFetcher.h" #include +#include #include namespace facebook::react { +extern const char ImageFetcherKey[] = "ImageFetcher"; + ImageFetcher::ImageFetcher( std::shared_ptr contextContainer) : contextContainer_(std::move(contextContainer)) {} @@ -29,9 +32,11 @@ ImageRequest ImageFetcher::requestImage( auto telemetry = std::make_shared(surfaceId); - flushImageRequests(); + if (!ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) { + flushImageRequests(); + } - return {imageSource, telemetry}; + return ImageRequest{imageSource, telemetry}; } void ImageFetcher::flushImageRequests() { diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h index d2703995e24685..d8a202de501ceb 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h @@ -16,6 +16,8 @@ namespace facebook::react { +extern const char ImageFetcherKey[]; + class ImageFetcher { public: ImageFetcher(std::shared_ptr contextContainer); @@ -25,15 +27,16 @@ class ImageFetcher { ImageFetcher(ImageFetcher &&) = delete; ImageFetcher &operator=(ImageFetcher &&) = delete; + void flushImageRequests(); + + private: + friend class ImageManager; ImageRequest requestImage( const ImageSource &imageSource, SurfaceId surfaceId, const ImageRequestParams &imageRequestParams, Tag tag); - private: - void flushImageRequests(); - std::unordered_map> items_; std::shared_ptr contextContainer_; }; diff --git a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp index 014979f8e26bf8..9f3f848cc6fb4c 100644 --- a/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp +++ b/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp @@ -22,10 +22,21 @@ constexpr inline bool isInteger(const std::string& str) { ImageManager::ImageManager( const std::shared_ptr& contextContainer) - : self_(new ImageFetcher(contextContainer)) {} + : contextContainer_(contextContainer), + self_(new std::shared_ptr( + std::make_shared(contextContainer))) { + if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) { + std::weak_ptr weakImageFetcher = + *static_cast*>(self_); + contextContainer->insert(ImageFetcherKey, weakImageFetcher); + } +} ImageManager::~ImageManager() { - delete static_cast(self_); + if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) { + contextContainer_->erase(ImageFetcherKey); + } + delete static_cast*>(self_); } ImageRequest ImageManager::requestImage( @@ -35,8 +46,9 @@ ImageRequest ImageManager::requestImage( Tag tag) const { if (ReactNativeFeatureFlags::enableImagePrefetchingAndroid()) { if (!isInteger(imageSource.uri)) { - return static_cast(self_)->requestImage( - imageSource, surfaceId, imageRequestParams, tag); + return static_cast*>(self_) + ->get() + ->requestImage(imageSource, surfaceId, imageRequestParams, tag); } } return {imageSource, nullptr, {}};