Skip to content

Commit 17f0ce9

Browse files
Image Prefetching > Re-enable JNI batching for ImageFetcher (facebook#54486)
Summary: This brings back another version of batching image request JNI calls. Previous attempts crashed in edge cases Changelog: [Internal] Reviewed By: lenaic Differential Revision: D86676643
1 parent 6355501 commit 17f0ce9

File tree

5 files changed

+46
-9
lines changed

5 files changed

+46
-9
lines changed

packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <react/renderer/core/EventBeat.h>
2525
#include <react/renderer/core/EventEmitter.h>
2626
#include <react/renderer/core/conversions.h>
27+
#include <react/renderer/imagemanager/ImageFetcher.h>
2728
#include <react/renderer/scheduler/Scheduler.h>
2829
#include <react/renderer/scheduler/SchedulerDelegate.h>
2930
#include <react/renderer/scheduler/SchedulerToolbox.h>
@@ -641,6 +642,19 @@ void FabricUIManagerBinding::schedulerShouldRenderTransactions(
641642
if (!mountingManager) {
642643
return;
643644
}
645+
646+
if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) {
647+
auto weakImageFetcher =
648+
scheduler_->getContextContainer()->find<std::weak_ptr<ImageFetcher>>(
649+
ImageFetcherKey);
650+
auto imageFetcher = weakImageFetcher.has_value()
651+
? weakImageFetcher.value().lock()
652+
: nullptr;
653+
if (imageFetcher != nullptr) {
654+
imageFetcher->flushImageRequests();
655+
}
656+
}
657+
644658
if (ReactNativeFeatureFlags::enableAccumulatedUpdatesInRawPropsAndroid()) {
645659
auto mountingTransaction = mountingCoordinator->pullTransaction(
646660
/* willPerformAsynchronously = */ true);

packages/react-native/ReactCommon/react/renderer/imagemanager/ImageManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class ImageManager {
3737
Tag tag = {}) const;
3838

3939
private:
40+
#ifdef ANDROID
41+
std::shared_ptr<const ContextContainer> contextContainer_{};
42+
#endif
4043
void *self_{};
4144
};
4245

packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
#include "ImageFetcher.h"
99

1010
#include <react/common/mapbuffer/JReadableMapBuffer.h>
11+
#include <react/featureflags/ReactNativeFeatureFlags.h>
1112
#include <react/renderer/imagemanager/conversions.h>
1213

1314
namespace facebook::react {
1415

16+
extern const char ImageFetcherKey[] = "ImageFetcher";
17+
1518
ImageFetcher::ImageFetcher(
1619
std::shared_ptr<const ContextContainer> contextContainer)
1720
: contextContainer_(std::move(contextContainer)) {}
@@ -29,9 +32,11 @@ ImageRequest ImageFetcher::requestImage(
2932

3033
auto telemetry = std::make_shared<ImageTelemetry>(surfaceId);
3134

32-
flushImageRequests();
35+
if (!ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) {
36+
flushImageRequests();
37+
}
3338

34-
return {imageSource, telemetry};
39+
return ImageRequest{imageSource, telemetry};
3540
}
3641

3742
void ImageFetcher::flushImageRequests() {

packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
namespace facebook::react {
1818

19+
extern const char ImageFetcherKey[];
20+
1921
class ImageFetcher {
2022
public:
2123
ImageFetcher(std::shared_ptr<const ContextContainer> contextContainer);
@@ -25,15 +27,16 @@ class ImageFetcher {
2527
ImageFetcher(ImageFetcher &&) = delete;
2628
ImageFetcher &operator=(ImageFetcher &&) = delete;
2729

30+
void flushImageRequests();
31+
32+
private:
33+
friend class ImageManager;
2834
ImageRequest requestImage(
2935
const ImageSource &imageSource,
3036
SurfaceId surfaceId,
3137
const ImageRequestParams &imageRequestParams,
3238
Tag tag);
3339

34-
private:
35-
void flushImageRequests();
36-
3740
std::unordered_map<SurfaceId, std::vector<ImageRequestItem>> items_;
3841
std::shared_ptr<const ContextContainer> contextContainer_;
3942
};

packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageManager.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,21 @@ constexpr inline bool isInteger(const std::string& str) {
2222

2323
ImageManager::ImageManager(
2424
const std::shared_ptr<const ContextContainer>& contextContainer)
25-
: self_(new ImageFetcher(contextContainer)) {}
25+
: contextContainer_(contextContainer),
26+
self_(new std::shared_ptr<ImageFetcher>(
27+
std::make_shared<ImageFetcher>(contextContainer))) {
28+
if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) {
29+
std::weak_ptr<ImageFetcher> weakImageFetcher =
30+
*static_cast<std::shared_ptr<ImageFetcher>*>(self_);
31+
contextContainer->insert(ImageFetcherKey, weakImageFetcher);
32+
}
33+
}
2634

2735
ImageManager::~ImageManager() {
28-
delete static_cast<ImageFetcher*>(self_);
36+
if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) {
37+
contextContainer_->erase(ImageFetcherKey);
38+
}
39+
delete static_cast<std::shared_ptr<ImageFetcher>*>(self_);
2940
}
3041

3142
ImageRequest ImageManager::requestImage(
@@ -35,8 +46,9 @@ ImageRequest ImageManager::requestImage(
3546
Tag tag) const {
3647
if (ReactNativeFeatureFlags::enableImagePrefetchingAndroid()) {
3748
if (!isInteger(imageSource.uri)) {
38-
return static_cast<ImageFetcher*>(self_)->requestImage(
39-
imageSource, surfaceId, imageRequestParams, tag);
49+
return static_cast<std::shared_ptr<ImageFetcher>*>(self_)
50+
->get()
51+
->requestImage(imageSource, surfaceId, imageRequestParams, tag);
4052
}
4153
}
4254
return {imageSource, nullptr, {}};

0 commit comments

Comments
 (0)