Summary:
There are a few places where we have JNI table ref leaks, and more places where we can aggressively clean up smart pointers immediately instead of waiting for them to be cleaned up at some later point.
In theory these smart pointers should be cleaned up immediately, but in cases where many components are being measured at once, the JNI table could grow until all measure calls are done. In extreme cases this
could cause a crash, which I want to avoid. At the very least, freeing memory more aggressively in this case can't hurt.
Changelog: [Internal]
Reviewed By: shergin
Differential Revision: D24293775
fbshipit-source-id: 159741ba955e5a6fe02caf6e65d1e4d6d4afadee
Summary:
This change maps the three most used colors (black, white, clear) to corresponding predefined values in UIColor. This should meaningfully reduce the overall amount of allocated UIColor/CGColor objects. In my non-scientific measures, it reduces the number of CGColor objects from ~1500 to ~1000. And... it no much at least in terms of kilobytes. However, I still think it's a good idea to implement this because I hope that can remove some work from memory allocation infra and maybe enable some optimizations that UIKit hopefully does for black and white colors. (I tend to believe that this optimization exists because UIKit even has a classes called UIDeviceWhiteColor and UICachedDeviceWhiteColor.)
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D23753506
fbshipit-source-id: 46e58dc7e6b0dcab3c83d29c7257c90ffbd95246
Summary:
This diff changes the implementation of `RCTCreateCGColorRefFromSharedColor` and `RCTUIColorFromSharedColor` in such a way that they don't rely on the fact that SharedColor is actually a `shared_ptr<CGColorRef>`. Instead, the methods just extract color components from SharedColor and create UIColor and CGColorRef objects on demand.
This allows us to change the implementation of SharedColor without worrying much about the rest of the system, which will do in the next diff.
Changelog: [Internal] Fabric-specific internal change.
Reviewed By: JoshuaGross
Differential Revision: D23753510
fbshipit-source-id: 340127527888776ebd5d241ed60c7e5220564013
Summary:
Every time we measure a TextInput we allocate a JNI local array and weren't cleaning it up, leading to JNI table exhaustion.
Changelog: [Internal]
Differential Revision: D23670780
fbshipit-source-id: 2ecf9770c8593eeadd70a248be58037fefdca61e
Summary:
Changelog: [Internal]
There was a key mismatch between what Java and C++.
cacheIdMap was incorrectly initialised.
Differential Revision: D23652342
fbshipit-source-id: 66f54dc887a011afeead9420bda093e9a0c9a8ca
Summary:
I noticed when porting my iOS app to macOS via Catalyst that the text rendering was somewhat different on the two platforms. Text looked blurry and over-weight on macOS, even when disabling the Catalyst scaling transform.
I hazily remembered that I'd seen this problem before in my old Cocoa development days: this kind of blurring occurs when rendering text with sub-pixel anti-aliasing into an offscreen buffer which will then be traditionally composited, because when the SPAA algorithm attempts to blend with the underlying content (i.e. in the offscreen buffer), there isn't any. SPAA is disabled on iOS, so the issue wouldn't appear there. On macOS, typical approachs to displaying text (e.g. `CATextLayer`) normally disable SPAA, since it's been incompatible with the platform's compositing strategy since the transition to layer-backed views some years ago. But React Native uses `NSLayoutManager` to rasterize text (rather than relying on the system render server via `CATextLayer`), and that class doesn't touch the context's font smoothing bit before drawing.
This change makes macOS/Catalyst text rendering consistent with iOS text rendering by disabling SPAA.
It appears that the code I've modified is in the process of being refactored (for Fabric?). It looks like [this](https://github.com/facebook/react-native/blob/8d6b41e9bcede07fb627d57cf6c11050ae590d57/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm#L111) is the corresponding place in the new code (sammy-SC, is that right?). I'm happy to include a change to the new renderer in this patch if someone can point me at how to test that change.
## Changelog
[iOS] [Fixed] - Improved text rendering on macOS Catalyst
Pull Request resolved: https://github.com/facebook/react-native/pull/29609
Test Plan:
1. Prepare RNTester for running on macOS (or apply [this patch](https://gist.github.com/andymatuschak/d0f5b4fc1a28efc4f860801aa1deddcd) to handle parts 1 and 2, but you'll still need to do part 3):
1. Open the workspace, navigate to the `RNTester` target's configuration, and check the "Mac" checkbox under "Deployment Info.
2. Flipper doesn't yet compile for Catalyst (https://github.com/facebook/react-native/issues/27845), so you must disable it by: a) commenting out `use_flipper!` and `flipper_post_install` in the Podfile, then running `pod install`; and b) removing the `FB_SONARKIT_ENABLED` preprocessor flags in the Xcode project.
3. macOS has different signing rules from iOS; you must set a development team in the "Signing & Capabilities" tab of the `RNTester` target configuration pane. Unfortunately, you must also do this in the `Pods` project for the `React-Core-AccessibilityResources` target ([this is an issue which CocoaPods must fix](https://github.com/CocoaPods/CocoaPods/issues/8891)).
2. Run RNTester with and without the patch. You'll see that the font hinting is overweight without the patch; see screenshots below (incorrect rendering above, correct rendering below; note that fonts still remain slightly blurred because of Catalyst's window scaling transform, but that's removed on Big Sur).


Reviewed By: PeteTheHeat
Differential Revision: D23344751
Pulled By: sammy-SC
fbshipit-source-id: 1bbf682b681e381a8a90e152245d9b0df8ec7697
Summary:
Simplify the TextInput measurement mechanism.
Now, data only flows from JS->C++->Java and from Java->JS. C++ passes along AttributedStrings from JS if JS updates, and otherwise Java maintains the only source of truth.
Previously we tried to keep all three in sync. This was complicated, slow, and even lead to some crashes.
This feels a bit hacky but I believe it's the simplest way to achieve this short-term. Ideally, we would use something like `AttributedStringBox` and pass that to State from Java,
but currently everything passed through the State system from Java must be serializable as `folly::dynamic`. So, instead, we just cache one Spannable per TextInput component and
use ReactTag as the cache identifier for lookup.
An interesting side-effect is that `measure` could race with TextInput updates, but the race condition favors measuring the latest text, not outdated values.
Followups:
- Can we do this without copying the EditText Spannable on every keystroke? Maybe this approach is too aggressive, but I don't want a background thread measuring a Spannable as it's being mutated.
- Do we need to support measuring Attachments?
- How can we clean up this API? It should work for now, but feels a little hacky.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D23290230
fbshipit-source-id: 832d2f397d30dfb17b77958af970d9c52a37e88b
Summary:
This diff extends the 'textlayoutmanager' module to compile in OSS
As part of this diff I also moved Android files in order to make the module compatible with Android.mk system
changelog: [internal] internal
Reviewed By: JoshuaGross
Differential Revision: D22963706
fbshipit-source-id: 14a7309f589fe12c21131c7d5cef02b4323d4a93
Summary:
This diff moves fabric C++ code from ReactCommon/fabric to ReactCommon/react/renderer
As part of this diff I also refactored components, codegen and callsites on CatalystApp, FB4A and venice
Script: P137350694
changelog: [internal] internal refactor
Reviewed By: fkgozali
Differential Revision: D22852139
fbshipit-source-id: f85310ba858b6afd81abfd9cbe6d70b28eca7415