Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -1911,8 +1911,6 @@ public class com/facebook/react/config/ReactFeatureFlags {
public static field enableViewRecycling Z
public static field excludeYogaFromRawProps Z
public static field fixStoppedSurfaceTagSetLeak Z
public static field reduceDeleteCreateMutation Z
public static field reduceDeleteCreateMutationLayoutAnimation Z
public static field rejectTurboModulePromiseOnNativeError Z
public static field traceTurboModulePromiseRejections Z
public static field unstable_bridgelessArchitectureMemoryPressureHackyBoltsFix Z
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,6 @@ public class ReactFeatureFlags {
*/
public static boolean enableRemoveDeleteTreeInstruction = false;

/**
* Allow fix in layout animation to drop delete...create mutations which could cause missing view
* state in Fabric SurfaceMountingManager.
*/
public static boolean reduceDeleteCreateMutationLayoutAnimation = true;

/**
* Allow fix to drop delete...create mutations which could cause missing view state in Fabric
* SurfaceMountingManager.
*/
public static boolean reduceDeleteCreateMutation = false;

/** Report mount operations from the host platform to notify mount hooks. */
public static boolean enableMountHooks = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,10 @@

namespace facebook::react {

constexpr static auto kReactFeatureFlagsJavaDescriptor =
"com/facebook/react/config/ReactFeatureFlags";

static bool getFeatureFlagValue(const char* name) {
static const auto reactFeatureFlagsClass =
jni::findClassStatic(kReactFeatureFlagsJavaDescriptor);
const auto field = reactFeatureFlagsClass->getStaticField<jboolean>(name);
return reactFeatureFlagsClass->getStaticFieldValue(field);
}

FabricMountingManager::FabricMountingManager(
std::shared_ptr<const ReactNativeConfig>& config,
jni::global_ref<JFabricUIManager::javaobject>& javaUIManager)
: javaUIManager_(javaUIManager),
reduceDeleteCreateMutation_(
getFeatureFlagValue("reduceDeleteCreateMutation")) {}
: javaUIManager_(javaUIManager) {}

void FabricMountingManager::onSurfaceStart(SurfaceId surfaceId) {
std::lock_guard lock(allocatedViewsMutex_);
Expand Down Expand Up @@ -288,30 +276,6 @@ void FabricMountingManager::executeMount(
case ShadowViewMutation::Create: {
bool shouldCreateView =
!allocatedViewTags.contains(newChildShadowView.tag);
if (reduceDeleteCreateMutation_) {
// Detect DELETE...CREATE situation on the same node and do NOT push
// back to the mount items. This is an edge case that may happen
// when for example animation runs while commit happened, and we
// want to filter them out here to capture all possible sources of
// such mutations. The re-ordering logic here assumes no
// DELETE...CREATE in the mutations, as we will re-order mutations
// and batch all DELETE instructions in the end.
auto it = std::remove_if(
cppDeleteMountItems.begin(),
cppDeleteMountItems.end(),
[&](auto& deletedMountItem) -> bool {
return deletedMountItem.oldChildShadowView.tag ==
newChildShadowView.tag;
});
bool hasDeletedViewsWithSameTag = it != cppDeleteMountItems.end();
cppDeleteMountItems.erase(it, cppDeleteMountItems.end());

if (hasDeletedViewsWithSameTag) {
shouldCreateView = false;
LOG(ERROR)
<< "XIN: Detect DELETE...CREATE on the same tag from mutations in the same batch. The DELETE and CREATE mutations are removed before sending to the native platforms";
}
}

if (shouldCreateView) {
cppCommonMountItems.push_back(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ class FabricMountingManager final {
allocatedViewRegistry_{};
std::recursive_mutex allocatedViewsMutex_;

const bool reduceDeleteCreateMutation_{false};

jni::local_ref<jobject> getProps(
const ShadowView& oldShadowView,
const ShadowView& newShadowView);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,6 @@ void LayoutAnimationKeyFrameManager::setComponentDescriptorRegistry(
componentDescriptorRegistry_ = componentDescriptorRegistry;
}

void LayoutAnimationKeyFrameManager::setReduceDeleteCreateMutation(
const bool reduceDeleteCreateMutation) {
reduceDeleteCreateMutation_ = reduceDeleteCreateMutation;
}

bool LayoutAnimationKeyFrameManager::shouldAnimateFrame() const {
std::scoped_lock lock(currentAnimationMutex_);
return currentAnimation_ || !inflightAnimations_.empty();
Expand Down Expand Up @@ -734,40 +729,6 @@ LayoutAnimationKeyFrameManager::pullTransaction(

auto finalConflictingMutations = ShadowViewMutationList{};
for (auto& keyFrame : conflictingAnimations) {
// Special-case: if the next conflicting animation contain "delete",
// while the final mutation has the same tag with "create", we should
// remove both the delete and create as they have no effect when
// combined in the same frame. The Fabric mount layer assumes no such
// combinations in the final mutations either.
if (reduceDeleteCreateMutation_) {
for (auto itMutation = immediateMutations.begin();
itMutation != immediateMutations.end();) {
auto& mutation = *itMutation;
bool hasCreateMutationDeletedWithSameTag = false;
if (mutation.newChildShadowView.tag == keyFrame.tag &&
mutation.type == ShadowViewMutation::Create) {
for (auto itKeyFrame = keyFrame.finalMutationsForKeyFrame.begin();
itKeyFrame != keyFrame.finalMutationsForKeyFrame.end();) {
auto& conflictFinalMutation = *itKeyFrame;
if (conflictFinalMutation.type == ShadowViewMutation::Delete) {
itKeyFrame =
keyFrame.finalMutationsForKeyFrame.erase(itKeyFrame);
hasCreateMutationDeletedWithSameTag = true;
break;
} else {
itKeyFrame++;
}
}
}

if (hasCreateMutationDeletedWithSameTag) {
itMutation = immediateMutations.erase(itMutation);
} else {
itMutation++;
}
}
}

// Special-case: if we have some (1) ongoing UPDATE animation,
// (2) it conflicted with a new MOVE operation (REMOVE+INSERT)
// without another corresponding UPDATE, we should re-queue the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
void setComponentDescriptorRegistry(const SharedComponentDescriptorRegistry&
componentDescriptorRegistry) override;

void setReduceDeleteCreateMutation(bool reduceDeleteCreateMutation) override;

// TODO: add SurfaceId to this API as well
bool shouldAnimateFrame() const override;

Expand Down Expand Up @@ -145,7 +143,6 @@ class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
mutable LayoutAnimationStatusDelegate* layoutAnimationStatusDelegate_{};
mutable std::mutex surfaceIdsToStopMutex_;
mutable std::unordered_set<SurfaceId> surfaceIdsToStop_{};
bool reduceDeleteCreateMutation_{false};

// Function that returns current time in milliseconds
std::function<uint64_t()> now_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,17 @@ Scheduler::Scheduler(
uiManager->registerCommitHook(*commitHook);
}

if (animationDelegate != nullptr) {
animationDelegate->setComponentDescriptorRegistry(
componentDescriptorRegistry_);
}
uiManager_->setAnimationDelegate(animationDelegate);

#ifdef ANDROID
removeOutstandingSurfacesOnDestruction_ = true;
reduceDeleteCreateMutationLayoutAnimation_ = reactNativeConfig_->getBool(
"react_fabric:reduce_delete_create_mutation_layout_animation_android");
#else
removeOutstandingSurfacesOnDestruction_ = reactNativeConfig_->getBool(
"react_fabric:remove_outstanding_surfaces_on_destruction_ios");
reduceDeleteCreateMutationLayoutAnimation_ = true;
#endif

#ifdef ANDROID
Expand All @@ -159,14 +162,6 @@ Scheduler::Scheduler(

CoreFeatures::enableReportEventPaintTime = reactNativeConfig_->getBool(
"rn_responsiveness_performance:enable_paint_time_reporting");

if (animationDelegate != nullptr) {
animationDelegate->setComponentDescriptorRegistry(
componentDescriptorRegistry_);
animationDelegate->setReduceDeleteCreateMutation(
reduceDeleteCreateMutationLayoutAnimation_);
}
uiManager_->setAnimationDelegate(animationDelegate);
}

Scheduler::~Scheduler() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,6 @@ class UIManagerAnimationDelegate {
virtual void setComponentDescriptorRegistry(
const SharedComponentDescriptorRegistry& componentDescriptorRegistry) = 0;

/**
* Set Animation flags for dropping delete and create mutations
*
* @param reduceDeleteCreateMutation
*/
virtual void setReduceDeleteCreateMutation(
bool reduceDeleteCreateMutation) = 0;

/**
* Only needed on Android to drive animations.
*/
Expand Down