Summary:
Followups to View Recycling diffs to improve things / clean up things a bit. This also fixes memory warnings which were not hooked up before.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D36707792
fbshipit-source-id: 410e70bf0eeec5569566138af547e1601394d0e6
Summary:
I'm finding it useful to keep track of a few additional numbers when doing perf analysis in Fabric.
Also making it easier to enable just these perf logs without all of the other verbose Fabric logs.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D36500518
fbshipit-source-id: e57e1e75131c5d59da876d1decb96d4da386f025
Summary:
This diff fixed an edge case that event dispatching is failed after pre-allocation of a view and before the view is mounted.
When a cached image is loaded, we will dispatch the event to JS immediately. This is could happen after the view is created during pre-allocation phase, when the event emitter is not instantiated yet. In that case, we will see [an error](https://github.com/facebook/react-native/blob/main/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java#L927) and the event will effectively be ignored.
To fix that we introduced a queue in this diff for those events. They will be dispatched in order when the view is mounted and the event emitter is non-null.
Changelog:
[Android][Fixed] - Fixed an edge case that event dispatching is failed after pre-allocation of a view and before the view is mounted.
Reviewed By: mullender
Differential Revision: D36331914
fbshipit-source-id: cd065b0b36978cb5f0aac793d8d16f07a48f0881
Summary:
Aligns two codepaths for measure, making sure we can use both MapBuffer and ReadableMap for measuring components.
Changelog: [Internal] - Align measure interface for MapBuffer experiment
Reviewed By: javache, mdvacca
Differential Revision: D34960317
fbshipit-source-id: a39eb84a0abb4414717463f2f1741e470be3531f
Summary:
remove duplicate code in FabricUIManager
The removed line is already called few lines above
changelog: [internal] internal
Reviewed By: JoshuaGross
Differential Revision: D34553849
fbshipit-source-id: 2e0102a77e7464c9803fb1175385fdafbb88f1fa
Summary:
Provides an alternative way of diffing props on Android side. Instead of passing dynamic JSON values from JS, the new approach diff C++ props and serializes difference into a `MapBuffer`. Current implementation does this only for `RCTView` component to test performance, correctness and memory impact (as MapBuffers are supposed to be more compact and performant).
This way of passing props allows for additional alignment between platforms, as C++ props are now source of truth for the view state, similar to iOS. At the same time, changing serialization method requires reimplementing `ViewManager` codegen (done manually for now) to account for `MapBuffer`s.
Changelog: [Added][Android] - Added an experimental prop serialization path based on MapBuffer
Reviewed By: mdvacca
Differential Revision: D33735245
fbshipit-source-id: 1515b5fe92f6557ae55abe215ce48277c83974a6
Summary:
This is a refactor of the logging of Fabric commit statistics to simplify the way we track performance points.
we'll later refactor and iterate on the API to integrate fabric perf point into developer tools
changelog: [internal] internal
Reviewed By: ShikaSD
Differential Revision: D34006700
fbshipit-source-id: 93a01accd90dfacc8b44edd158033b442a843284
Summary:
Changelog: [Internal]
Remove all the MCs that enable SVCs in Fabric, because we'll only test SVCs in Bridgeless mode to simplify rollout. There were complications with enabling SVCs in Fabric at a previous rollout.
Reviewed By: RSNara
Differential Revision: D33861243
fbshipit-source-id: fdbfedce77f8bd1bab2a807237017787ae8bf7c1
Summary:
This diff adds extra logging to track how long does it take to exeucte different stages of the fabric commit
changelog: [internal] internal
Reviewed By: philIip
Differential Revision: D33183070
fbshipit-source-id: 69e31bef69c9d9ec57dc7e00e4c36e278eb30cb6
Summary:
Some of the prerendered surfaces rely on Android context being present to have correct theming (e.g. for platform colors) and measurements of platform components. This change uses context provided to initialize the surface as themed context before view is attached.
This way it is possible to configure theming with `ContextThemeWrapper` the same way as Litho does it for prerendering. The assumption is that any kind of customization done through Android theme will be applied from prerendering entry point as well.
Changelog: [Internal] - Use context from surface for prerendering
Reviewed By: mdvacca
Differential Revision: D31906091
fbshipit-source-id: 344fc96eb2f85ba5b762bee64d1a29443b3fd1d3
Summary:
Propagate event category definition to every event that is using `dispatchModernV2` (gated in production), providing opportunity to override categories of some events if needed. No events are meaningfully affected by this change, as coalesced events (e.g. scroll) are always dispatched as continuous and touch events are handled separately.
Changelog:
[Internal] Expose event category in Event class
Reviewed By: cortinico
Differential Revision: D31276249
fbshipit-source-id: f9a756b3a5cf5897e17209f3d0aed6a1c16cbd2e
Summary:
Updates event category deduction to match iOS implementation.
The event priority is used by concurrent mode to prioritize certain events, where Cxx part already assigns the correct priority based on the `ContinuousStart` -> `ContinuousEnd` spans. These spans can be deduced from the touch events, which we do in this implementation.
All events that can be "coalesced" (dispatched through `invokeUnique`) are assigned `Continuous` by default in Fabric core, so scroll/slider change events will never be discrete.
Changelog:
[Internal] Add category deduction to Android touch events
Reviewed By: mdvacca
Differential Revision: D31233233
fbshipit-source-id: f5b039aa137f1b4d2e2b15578bfc29ab6903a081
Summary:
Update FabricUIManager methods for `SurfaceHandler` to start usual rendering or prerendering based on presence of the view instead of using two methods with same logic.
Changelog: [Internal]
Reviewed By: sshic
Differential Revision: D30346502
fbshipit-source-id: 297f2b4a16dc7af7c36379252bd73e6dc953ff59
Summary:
ReactSoftException makes it seem like the class is an Exception, when it's actually a logger. This rename I think is more appropriate.
Changelog: [Internal]
Reviewed By: JoshuaGross
Differential Revision: D30251735
fbshipit-source-id: 550bd543388e698774ec31753200bd3f722d8c17
Summary:
This diff exposes a new API in FabricUIManager called getInspectorDataForInstance. The goal of this method is to return React metadata for a Native view.
This data will be used from partner teams to build tools that uses React metadata in RN
Data returned from React: P429701924
changelog: [internal] internal
allow-large-files
Reviewed By: JoshuaGross
Differential Revision: D29747864
fbshipit-source-id: 8cb55573be08cb530f7e3c83eed8b4fcf43e7781
Summary:
Always create a new EventEmitter specifically for Fabric when initializing the Fabric JSI module.
Previously, we were (sometimes!) reusing the EventEmitter being used for the old renderer and they were shared. There doesn't seem to be a compelling reason to continue doing this, and Fabric has optimized EventEmitters that we can use instead.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D29724537
fbshipit-source-id: 1b2c7a7d656e3fb86ddf98a6cf0f2e67dcbf8aef
Summary:
It is possible for receiveEvent to be called concurrently with/after destruction of FabricUIManager. Drop events if we are able to detect that case.
Changelog: [Internal]
Reviewed By: sshic
Differential Revision: D29596271
fbshipit-source-id: 1fa50d9c3cff0bf578316d905966e1bdfffe94d1
Summary:
Changelog: [internal]
We should be calling invokeUnique if event can be coalesced, not the other way around.
Reviewed By: JoshuaGross
Differential Revision: D29194528
fbshipit-source-id: 36e4ae71254420ef47deea436cad20eec09712fc
Summary:
The mount items executed before the view attach can fail with the RetryableMountingLayerException, which we should either retry or skip the item. This change updates logic for such items to catch these exceptions.
Instead of passing `MountingManager` to execute the items, this change now passes a reference to the `MountItemDispatcher` (abstracted through interface to resolve cycle between the manager and dispatcher). The dispatcher executes the queue directly and schedules retry together with the next batch.
Changelog: [Internal]
Reviewed By: JoshuaGross
Differential Revision: D29068063
fbshipit-source-id: 04030b21db188d5617c3448322d25ba77d5fbb9f
Summary:
This is a re-land of D28810022 (https://github.com/facebook/react-native/commit/7e9c741146e1b3aa542ecfe138765e95ddddac3f), which was reverted due to T92179998. The fix is in D28938530. This issue could also be resolved by preventing more view preallocations (D28811419 (https://github.com/facebook/react-native/commit/8ca18f0b602a08cd9a5c9f6681bb5dc74e0d34f7)).
---
EventEmitter is not transmitted from C++ to Java until an UPDATE operation is enqueued.
Practically this usually happens "right away", but in the case of an Image component, especially, the EventEmitter could be missing while events are being fired from the native side (for example, loading events).
The fix is just to pass EventEmitter in sooner, in both Create and Preallocate. There should be no ill effect since EventEmitter is nullable anyway.
One potential side-effect: since Views can be PreAllocated and potentially never deallocated until StopSurface is called, this could result in more EventEmitter objects being leaked and retained from Java. I believe the fix is to remove PreAllocated Views more aggressively.
Changelog: [Internal]
Reviewed By: sammy-SC
Differential Revision: D28938637
fbshipit-source-id: c9e290a24ed15c28881e3eead4a5f580f66b288f
Summary:
setJSResponder/clearJSResponder have been in use in prod for a while and are stable. Ship them in code.
Changelog: [Internal]
Reviewed By: sammy-SC
Differential Revision: D28889894
fbshipit-source-id: 1c42526cd890d528062eeb50761fc49cc6109d76
Summary:
EventEmitter is not transmitted from C++ to Java until an UPDATE operation is enqueued. Practically this usually happens "right away", but in the case of an Image component, especially, the EventEmitter could be missing while events are being fired from the native side (for example, loading events).
The fix is just to pass EventEmitter in sooner, in both Create and Preallocate. There should be no ill effect since EventEmitter is nullable anyway.
One potential side-effect: since Views can be PreAllocated and potentially never deallocated until StopSurface is called, this could result in more EventEmitter objects being leaked and retained from Java. I believe the fix is to remove PreAllocated Views more aggressively.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28810022
fbshipit-source-id: ae4c8b4eefe619d9a99fa5f90f612d6dd4880da5
Summary:
TL;DR: simplify and delete a bunch of stuff that shouldn't be necessary in Fabric.
I discovered that this event dispatcher (and the older one this is based on) is triple-queueing: we queue events into "staging", and then post "dispatch events" to only run /on the JS thread/. Even in Fabric. Then, each of these events is emitted into C++ where they are queued /again/! This refactor eliminates one more level of queueing - instead of scheduling dispatch for the JS thread, we just emit them directly to C++ when they're received in Java.
Unfortunately, the EventDispatcher is also used to drive AsyncEventBeat in C++:
1. EventBeatManager.onBatchEventDispatched: https://fburl.com/diffusion/qf6dyhsw
In the C++ impl, it indirectly will drive the AsyncEventBeat/AsyncEventBeatV2.
2. onBatchEventDispatched is ONLY called from EventDispatcherImpl: https://fburl.com/codesearch/mxk8ifyj
3. Which is queued and only runs on the JS thread: https://fburl.com/codesearch/czvbst4u
This means the AsyncEventBeat is only ticked when the JS thread is free, and ticks will be skipped when the JS thread is occupied for long periods.
Now, in this refactor, when this class is used it will drive AsyncEventBeat on every UI tick. This is also potentially not correct. On iOS (Fabric), AsyncEventBeat is driven when the UI thread is "about to sleep".
For now I'm not going to worry about that detail - it is significant, but Fabric+Android is currently /not doing the right thing/ and it's not clear that we want to maintain iOS behavior. This is something we need to discuss further and figure out.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28654033
fbshipit-source-id: b3cb9b706343c8dd3c4cf84f24388908c57e2138
Summary:
EventDispatcherImpl uses synchronized blocks all over to make it thread-safe. I'm concerned about the perf implications of this and creating contention between JS and UI threads.
This is locked behind a feature flag.
Enabled only for Fabric in StaticViewConfig mode, and a feature flag, for now.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28591331
fbshipit-source-id: ea8f93a2e1343ce37fa78690dcb62fe03594120f
Summary:
Changelog: [Internal]
Links APIs in Fabric and Venice to create a surface without a view and mount it separately when surface is started the usual way.
Reviewed By: mdvacca
Differential Revision: D27339365
fbshipit-source-id: d1b674ce856957465eb6f3a5d7f26eb0ab625353
Summary:
Instead of annotating individual methods with DoNotStrip, we actually want to ensure that nothing in this class gets stripped out.
This also upgrades the yoga/proguard-annotations package for Gradle builds.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D27335181
fbshipit-source-id: 5b696c26faf4d1b32a3fd885e42a996aff23f0be
Summary:
Changelog: [Internal]
FabricUIManager contains a lot of logic related to mounting items and manipulating dispatch queues, which can be safely extracted outside. Apart from decreased logical complexity, this change enables easier modification of the queuing behavior later in this stack.
Majority of the changes is caused by moving existing logic to a different class, no change in behavior expected.
Reviewed By: JoshuaGross
Differential Revision: D27271116
fbshipit-source-id: 86fe45b19bb839f96fde8ba607f72006f6401cc7
Summary:
This diff contains the code from the 35 diff stack - D27210587
This diff implement and integrates Mapbuffer into Fabric text measure system
changelog: [internal] internal
Reviewed By: JoshuaGross
Differential Revision: D27241836
fbshipit-source-id: f40a780df0723f27da440f709a8676cfcca63953
Summary:
Create MC to gate execution of JS Responder in Fabric Android
MC.react_fabric.enable_js_responder_fabric_android is enabled by default in the server
changelog: [internal] internal
Reviewed By: JoshuaGross
Differential Revision: D26905296
fbshipit-source-id: 82504174394d1e10fd017435cccd38952404fda0
Summary:
Changelog: [Internal]
Updates `ReactSurface` to use `SurfaceHandler` internally.
This removes most of the internal state in `ReactSurface` and propagates all the calls to the `SurfaceHandler`.
`FabricUIManager` now uses `SurfaceHandler` to start/stop the surface.
SurfaceId is still used for view operations. SurfaceId is also now mutable to play better with existing Android infra.
Reviewed By: shergin, mdvacca
Differential Revision: D26112992
fbshipit-source-id: 52e6860084d739381317035dc3011956d452063c
Summary:
Simplify addLifecycleEventListener for the flaky test because we just want to test that listener is working.
Changelog:
[Android][Changed] - Add a spare implementation of addLifecycleEventListener for test purpose.
Reviewed By: PeteTheHeat
Differential Revision: D26749256
fbshipit-source-id: 5af216e6bfa37a15eb189aa24a3df35a7a7112de
Summary:
This diff moves the method getViewportOffset out of ReactRootView. This is necessary to avoid Fabric to depend from paper.
changelog: [internal] internal
Reviewed By: JoshuaGross
Differential Revision: D26716901
fbshipit-source-id: cec67c24860a776fb361d7cda08d3142e1214c8c
Summary:
In Fabric we're seeing setJSResponderHandler called during teardown of a surface, which causes a crash because the SurfaceId is no longer available at that point.
Guard against setJSResponderHandler being called on a dead surface.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D26734786
fbshipit-source-id: 838d682ee0dd1d4de49993fa479dc2097cf33521
Summary:
Change lifecycle of stopSurface in a subtle way: mark the surface as stopped in Java first, then in Cxx (currently it happens in Cxx, then Java).
This will cause us / allow us to ignore the final mounting instructions for the Surface, which are all irrelevant since they just have to do with View removal.
We can rely on GC and `unmountReactApplication` to do all of this for us, and save some CPU cycles on stopSurface.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D26469741
fbshipit-source-id: a7f81d44c3cb2138f0ab31feb38852910410c638
Summary:
This diff refactor the initialization and deallocation of EventDispatcher in FabricUIManager when StaticViewConfigs are enabled.
The goal of this diff is to make sure that the EventDispatcher is deallocated correctly when using StaticViewConfigs
changelog: [internal]
Reviewed By: JoshuaGross
Differential Revision: D26166413
fbshipit-source-id: e5bdad7ba923edc677c6b73f3a4d1271941f41cc
Summary:
There is a race between PreAllocateMountItems executing and killing off stale SurfaceMountingManagers.
For now I'm simplifying the "eviction" mechanism. We just keep up to 15 SurfaceMountingManagers around and start evicting them from the least-recently-referenced one.
Hopefully this logic can be simplified in the future.
I'm also sneaking in a small perf optimization for PreAllocateMountItem: don't queue them if the associated surface is already stopped, because chewing through a bunch of dead PreAllocateMountItems on the UI thread can be expensive.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D26059378
fbshipit-source-id: 3b2503d7d8e5f045ae741d0d4a5880d1b37758d2
Summary:
In some cases, onMeasure/onLayout are called on the RootView before `startSurface` in Fabric has been able to set surfaceId on the RootView.
With the new SurfaceMountingManager, this causes a crash because we need a valid surfaceId to perform an operation. Before the SurfaceMountingManager refactor, a surfaceId of 0 would be passed to `mBinding.setConstraints` in the FabricUIManager, and setConstraints in C++ noops if there's an invalid surfaceId.
For now, FabricUIManager will also fail silently if the surfaceId is invalid when updateRootLayoutSpecs is called, just to be conservative and to be consistent with previous behavior. This will be upgraded to a hard-crash in the future.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D26051266
fbshipit-source-id: ca2d80f899cdba9b3962af68546bd83b77be0680