Skip to content

Commit 4711ba9

Browse files
Image Prefetching > Re-enable JNI batching for ImageFetcher (#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 7ea375d commit 4711ba9

File tree

4 files changed

+45
-10
lines changed

4 files changed

+45
-10
lines changed

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

Lines changed: 13 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>
@@ -636,6 +637,18 @@ void FabricUIManagerBinding::schedulerDidFinishTransaction(
636637

637638
void FabricUIManagerBinding::schedulerShouldRenderTransactions(
638639
const std::shared_ptr<const MountingCoordinator>& mountingCoordinator) {
640+
if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) {
641+
auto weakImageFetcher =
642+
scheduler_->getContextContainer()->find<std::weak_ptr<ImageFetcher>>(
643+
ImageFetcherKey);
644+
auto imageFetcher = weakImageFetcher.has_value()
645+
? weakImageFetcher.value().lock()
646+
: nullptr;
647+
if (imageFetcher != nullptr) {
648+
imageFetcher->flushImageRequests();
649+
}
650+
}
651+
639652
auto mountingManager =
640653
getMountingManager("schedulerShouldRenderTransactions");
641654
if (!mountingManager) {

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,23 @@
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)) {}
1821

22+
ImageFetcher::~ImageFetcher() noexcept {
23+
if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) {
24+
contextContainer_->erase(ImageFetcherKey);
25+
}
26+
}
27+
1928
ImageRequest ImageFetcher::requestImage(
2029
const ImageSource& imageSource,
2130
SurfaceId surfaceId,
@@ -29,9 +38,11 @@ ImageRequest ImageFetcher::requestImage(
2938

3039
auto telemetry = std::make_shared<ImageTelemetry>(surfaceId);
3140

32-
flushImageRequests();
41+
if (!ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) {
42+
flushImageRequests();
43+
}
3344

34-
return {imageSource, telemetry};
45+
return ImageRequest{imageSource, telemetry};
3546
}
3647

3748
void ImageFetcher::flushImageRequests() {

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,27 @@
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);
22-
~ImageFetcher() = default;
24+
~ImageFetcher() noexcept;
2325
ImageFetcher(const ImageFetcher &) = delete;
2426
ImageFetcher &operator=(const ImageFetcher &) = delete;
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: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,17 @@ 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+
: self_(new std::shared_ptr<ImageFetcher>(
26+
std::make_shared<ImageFetcher>(contextContainer))) {
27+
if (ReactNativeFeatureFlags::enableImagePrefetchingJNIBatchingAndroid()) {
28+
std::weak_ptr<ImageFetcher> weakImageFetcher =
29+
*static_cast<std::shared_ptr<ImageFetcher>*>(self_);
30+
contextContainer->insert(ImageFetcherKey, weakImageFetcher);
31+
}
32+
}
2633

2734
ImageManager::~ImageManager() {
28-
delete static_cast<ImageFetcher*>(self_);
35+
delete static_cast<std::shared_ptr<ImageFetcher>*>(self_);
2936
}
3037

3138
ImageRequest ImageManager::requestImage(
@@ -35,8 +42,9 @@ ImageRequest ImageManager::requestImage(
3542
Tag tag) const {
3643
if (ReactNativeFeatureFlags::enableImagePrefetchingAndroid()) {
3744
if (!isInteger(imageSource.uri)) {
38-
return static_cast<ImageFetcher*>(self_)->requestImage(
39-
imageSource, surfaceId, imageRequestParams, tag);
45+
return static_cast<std::shared_ptr<ImageFetcher>*>(self_)
46+
->get()
47+
->requestImage(imageSource, surfaceId, imageRequestParams, tag);
4048
}
4149
}
4250
return {imageSource, nullptr, {}};

0 commit comments

Comments
 (0)