From e2d2ded5bad8c49ef3f3b54e3c219cdfc40c3b3a Mon Sep 17 00:00:00 2001 From: Peter Abbondanzo Date: Thu, 13 Nov 2025 14:08:19 -0800 Subject: [PATCH] Fix jagged edge rendering on API 28 (#54525) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/54525 Older versions of Android's clipPath APIs do not properly support antialiasing and BackgroundStyleApplicator relies on this API to clip to border radii that are smaller than provided images or views. As a result, this often leaves jagged edges on the outer edges of these images. Android even calls this out in their documentation under the "Canvas.clipPath" section of https://developer.android.com/topic/performance/vitals/render#common-jank. This change introduces a new API in BackgroundStyleApplicator called `clipToPaddingBoxWithAntiAliasing` which takes an additional argument over the existing `clipToPaddingBox`: a draw call. If non-null and the Android API is 28 or lower, a new drawPath operation is used to mark the pixels outside of the drawn contents as transparent. Changelog: [Android][Fixed] - Fixed antialiasing issues from border radius usage in API <= 28 Reviewed By: haixia-meta Differential Revision: D86263195 --- .../ReactAndroid/api/ReactAndroid.api | 1 + .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../uimanager/BackgroundStyleApplicator.kt | 86 ++++++++- .../react/views/image/ReactImageView.kt | 21 ++- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 168 ++++++++++-------- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 11 ++ .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 23 files changed, 308 insertions(+), 105 deletions(-) diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 7998d196e3a9..609d4db59582 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -3228,6 +3228,7 @@ public abstract interface class com/facebook/react/turbomodule/core/interfaces/T public final class com/facebook/react/uimanager/BackgroundStyleApplicator { public static final field INSTANCE Lcom/facebook/react/uimanager/BackgroundStyleApplicator; public static final fun clipToPaddingBox (Landroid/view/View;Landroid/graphics/Canvas;)V + public static final fun clipToPaddingBoxWithAntiAliasing (Landroid/view/View;Landroid/graphics/Canvas;Lkotlin/jvm/functions/Function0;)V public static final fun getBackgroundColor (Landroid/view/View;)Ljava/lang/Integer; public static final fun getBorderColor (Landroid/view/View;Lcom/facebook/react/uimanager/style/LogicalEdge;)Ljava/lang/Integer; public static final fun getBorderRadius (Landroid/view/View;Lcom/facebook/react/uimanager/style/BorderRadiusProp;)Lcom/facebook/react/uimanager/LengthPercentage; diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 7ea9952904bc..22e5c45b0cdd 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<10999fe360a25451c316eed2d27b6d92>> + * @generated SignedSource<> */ /** @@ -114,6 +114,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = accessor.enableAccumulatedUpdatesInRawPropsAndroid() + /** + * Enable antialiased border radius clipping for Android API 28 and below using manual masking with Porter-Duff compositing + */ + @JvmStatic + public fun enableAndroidAntialiasedBorderRadiusClipping(): Boolean = accessor.enableAndroidAntialiasedBorderRadiusClipping() + /** * Enables linear text rendering on Android wherever subpixel text rendering is enabled */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index ffe00e589b04..07fd572bace0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -34,6 +34,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var disableViewPreallocationAndroidCache: Boolean? = null private var enableAccessibilityOrderCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null + private var enableAndroidAntialiasedBorderRadiusClippingCache: Boolean? = null private var enableAndroidLinearTextCache: Boolean? = null private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null @@ -235,6 +236,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableAndroidAntialiasedBorderRadiusClipping(): Boolean { + var cached = enableAndroidAntialiasedBorderRadiusClippingCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableAndroidAntialiasedBorderRadiusClipping() + enableAndroidAntialiasedBorderRadiusClippingCache = cached + } + return cached + } + override fun enableAndroidLinearText(): Boolean { var cached = enableAndroidLinearTextCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index 92b05a433c7e..7af178089c9a 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -56,6 +56,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun enableAndroidAntialiasedBorderRadiusClipping(): Boolean + @DoNotStrip @JvmStatic public external fun enableAndroidLinearText(): Boolean @DoNotStrip @JvmStatic public external fun enableAndroidTextMeasurementOptimizations(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index f74287c5525a..a02742302dcc 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4b24bc3165b6ab1583efc8e1a22444ed>> + * @generated SignedSource<<30ca2685ceb6f2733531f5e7fce4416d>> */ /** @@ -51,6 +51,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = false + override fun enableAndroidAntialiasedBorderRadiusClipping(): Boolean = false + override fun enableAndroidLinearText(): Boolean = false override fun enableAndroidTextMeasurementOptimizations(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 2f15ce930e5f..271f53a00759 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<6d1a15e64f42cc7d8869300720276215>> */ /** @@ -38,6 +38,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var disableViewPreallocationAndroidCache: Boolean? = null private var enableAccessibilityOrderCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null + private var enableAndroidAntialiasedBorderRadiusClippingCache: Boolean? = null private var enableAndroidLinearTextCache: Boolean? = null private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null @@ -253,6 +254,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun enableAndroidAntialiasedBorderRadiusClipping(): Boolean { + var cached = enableAndroidAntialiasedBorderRadiusClippingCache + if (cached == null) { + cached = currentProvider.enableAndroidAntialiasedBorderRadiusClipping() + accessedFeatureFlags.add("enableAndroidAntialiasedBorderRadiusClipping") + enableAndroidAntialiasedBorderRadiusClippingCache = cached + } + return cached + } + override fun enableAndroidLinearText(): Boolean { var cached = enableAndroidLinearTextCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index 4a1df79aa743..cf2b0ad4480d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<90fd5f8d9c5b6833c6fdd10167577bb9>> + * @generated SignedSource<<48d0d5486793b60914cfd595f0fc78d1>> */ /** @@ -51,6 +51,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean + @DoNotStrip public fun enableAndroidAntialiasedBorderRadiusClipping(): Boolean + @DoNotStrip public fun enableAndroidLinearText(): Boolean @DoNotStrip public fun enableAndroidTextMeasurementOptimizations(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt index 6fa57f5aeaee..a84dd86fbc4f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BackgroundStyleApplicator.kt @@ -9,7 +9,10 @@ package com.facebook.react.uimanager import android.graphics.Canvas import android.graphics.Color +import android.graphics.Paint import android.graphics.Path +import android.graphics.PorterDuff +import android.graphics.PorterDuffXfermode import android.graphics.Rect import android.graphics.RectF import android.graphics.drawable.Drawable @@ -19,6 +22,7 @@ import android.widget.ImageView import androidx.annotation.ColorInt import com.facebook.react.bridge.ReadableArray import com.facebook.react.common.annotations.UnstableReactNativeAPI +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags import com.facebook.react.uimanager.PixelUtil.dpToPx import com.facebook.react.uimanager.PixelUtil.pxToDp import com.facebook.react.uimanager.common.UIManagerType @@ -481,12 +485,36 @@ public object BackgroundStyleApplicator { */ @JvmStatic public fun clipToPaddingBox(view: View, canvas: Canvas) { + clipToPaddingBoxWithAntiAliasing(view, canvas, null) + } + + /** + * Clips the canvas to the padding box of the view. + * + * The padding box is the area within the borders of the view, accounting for border radius if + * present. + * + * On Android 28 and below, when border radius is present, this uses an antialiased clipping + * approach with Porter-Duff compositing to avoid jagged edges. The drawContent lambda is invoked + * to draw the actual content after setting up the layer but before applying the mask. + * + * @param view The view whose padding box defines the clipping region + * @param canvas The canvas to clip + * @param drawContent Lambda that draws the content after clipping is set up + */ + @JvmStatic + public fun clipToPaddingBoxWithAntiAliasing( + view: View, + canvas: Canvas, + drawContent: (() -> Unit)?, + ) { val drawingRect = Rect() view.getDrawingRect(drawingRect) val composite = getCompositeBackgroundDrawable(view) if (composite == null) { canvas.clipRect(drawingRect) + drawContent?.invoke() return } @@ -508,15 +536,69 @@ public object BackgroundStyleApplicator { paddingBoxRect, computedBorderInsets, ) - paddingBoxPath.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat()) - canvas.clipPath(paddingBoxPath) + + // On Android 28 and below, use antialiased clipping with Porter-Duff compositing. On newer + // Android versions, use the standard clipPath. + if ( + ReactNativeFeatureFlags.enableAndroidAntialiasedBorderRadiusClipping() && + Build.VERSION.SDK_INT <= Build.VERSION_CODES.P && + view.width > 0 && + view.height > 0 && + drawContent != null + ) { + clipWithAntiAliasing( + view, + canvas, + paddingBoxPath, + drawContent, + ) + } else { + canvas.clipPath(paddingBoxPath) + drawContent?.invoke() + } } else { paddingBoxRect.offset(drawingRect.left.toFloat(), drawingRect.top.toFloat()) canvas.clipRect(paddingBoxRect) + drawContent?.invoke() } } + /** + * Applies antialiased clipping using Porter-Duff compositing for Android 28 and below. This draws + * content to a layer, then applies an antialiased mask to clip it. + */ + private fun clipWithAntiAliasing( + view: View, + canvas: Canvas, + paddingBoxPath: Path, + drawContent: () -> Unit, + ) { + // Save the layer for Porter-Duff compositing + val saveCount = canvas.saveLayer(0f, 0f, view.width.toFloat(), view.height.toFloat(), null) + + // Draw the content first + drawContent() + + // Create the antialiased mask path with Porter-Duff DST_IN to clip + val maskPaint = Paint(Paint.ANTI_ALIAS_FLAG) + maskPaint.style = Paint.Style.FILL + maskPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_IN) + + // Transparent pixels with INVERSE_WINDING only works on API 28 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + maskPaint.color = Color.TRANSPARENT + paddingBoxPath.setFillType(Path.FillType.INVERSE_WINDING) + } else { + maskPaint.color = Color.BLACK + } + + canvas.drawPath(paddingBoxPath, maskPaint) + + // Restore the layer + canvas.restoreToCount(saveCount) + } + /** * Resets the background styling of the view to its original state. * diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt index 233989e634e8..ecbcc9b3083b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.kt @@ -372,15 +372,18 @@ public class ReactImageView( public override fun hasOverlappingRendering(): Boolean = false public override fun onDraw(canvas: Canvas) { - BackgroundStyleApplicator.clipToPaddingBox(this, canvas) - try { - super.onDraw(canvas) - } catch (e: RuntimeException) { - // Only provide updates if downloadListener is set (shouldNotify is true) - if (downloadListener != null) { - val eventDispatcher = - UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id) - eventDispatcher?.dispatchEvent(createErrorEvent(UIManagerHelper.getSurfaceId(this), id, e)) + BackgroundStyleApplicator.clipToPaddingBoxWithAntiAliasing(this, canvas) { + try { + super.onDraw(canvas) + } catch (e: RuntimeException) { + // Only provide updates if downloadListener is set (shouldNotify is true) + if (downloadListener != null) { + val eventDispatcher = + UIManagerHelper.getEventDispatcherForReactTag(context as ReactContext, id) + eventDispatcher?.dispatchEvent( + createErrorEvent(UIManagerHelper.getSurfaceId(this), id, e) + ) + } } } } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 667b0131f9e7..c3821f79f8e0 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5e4e22e976ce1724191c7b7e381ea5a1>> */ /** @@ -123,6 +123,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool enableAndroidAntialiasedBorderRadiusClipping() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableAndroidAntialiasedBorderRadiusClipping"); + return method(javaProvider_); + } + bool enableAndroidLinearText() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableAndroidLinearText"); @@ -641,6 +647,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableAccumulatedUpdatesInRawPropsAndro return ReactNativeFeatureFlags::enableAccumulatedUpdatesInRawPropsAndroid(); } +bool JReactNativeFeatureFlagsCxxInterop::enableAndroidAntialiasedBorderRadiusClipping( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableAndroidAntialiasedBorderRadiusClipping(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableAndroidLinearText( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableAndroidLinearText(); @@ -1084,6 +1095,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableAccumulatedUpdatesInRawPropsAndroid", JReactNativeFeatureFlagsCxxInterop::enableAccumulatedUpdatesInRawPropsAndroid), + makeNativeMethod( + "enableAndroidAntialiasedBorderRadiusClipping", + JReactNativeFeatureFlagsCxxInterop::enableAndroidAntialiasedBorderRadiusClipping), makeNativeMethod( "enableAndroidLinearText", JReactNativeFeatureFlagsCxxInterop::enableAndroidLinearText), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 4ad4b27dd370..9d7a8cee4f48 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<066e98c5620ccf67d9e4ceb9d66b08f0>> + * @generated SignedSource<<1cb8ed4a72e9d2b8dd34694485704f60>> */ /** @@ -72,6 +72,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableAccumulatedUpdatesInRawPropsAndroid( facebook::jni::alias_ref); + static bool enableAndroidAntialiasedBorderRadiusClipping( + facebook::jni::alias_ref); + static bool enableAndroidLinearText( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 68c9c1b3b1be..d43070ee5b91 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<82169671bfbd5f83639cc50fcb710670>> + * @generated SignedSource<<9c10486574fdff78933aed6acd90533c>> */ /** @@ -82,6 +82,10 @@ bool ReactNativeFeatureFlags::enableAccumulatedUpdatesInRawPropsAndroid() { return getAccessor().enableAccumulatedUpdatesInRawPropsAndroid(); } +bool ReactNativeFeatureFlags::enableAndroidAntialiasedBorderRadiusClipping() { + return getAccessor().enableAndroidAntialiasedBorderRadiusClipping(); +} + bool ReactNativeFeatureFlags::enableAndroidLinearText() { return getAccessor().enableAndroidLinearText(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 551a3e0f7cd7..035e1b422906 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<72ed560f90d44db777469315e0865c6c>> */ /** @@ -109,6 +109,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableAccumulatedUpdatesInRawPropsAndroid(); + /** + * Enable antialiased border radius clipping for Android API 28 and below using manual masking with Porter-Duff compositing + */ + RN_EXPORT static bool enableAndroidAntialiasedBorderRadiusClipping(); + /** * Enables linear text rendering on Android wherever subpixel text rendering is enabled */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 4616c4d7eb23..6e44121101a3 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -281,6 +281,24 @@ bool ReactNativeFeatureFlagsAccessor::enableAccumulatedUpdatesInRawPropsAndroid( return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableAndroidAntialiasedBorderRadiusClipping() { + auto flagValue = enableAndroidAntialiasedBorderRadiusClipping_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(14, "enableAndroidAntialiasedBorderRadiusClipping"); + + flagValue = currentProvider_->enableAndroidAntialiasedBorderRadiusClipping(); + enableAndroidAntialiasedBorderRadiusClipping_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableAndroidLinearText() { auto flagValue = enableAndroidLinearText_.load(); @@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAndroidLinearText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableAndroidLinearText"); + markFlagAsAccessed(15, "enableAndroidLinearText"); flagValue = currentProvider_->enableAndroidLinearText(); enableAndroidLinearText_ = flagValue; @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAndroidTextMeasurementOptimizations( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableAndroidTextMeasurementOptimizations"); + markFlagAsAccessed(16, "enableAndroidTextMeasurementOptimizations"); flagValue = currentProvider_->enableAndroidTextMeasurementOptimizations(); enableAndroidTextMeasurementOptimizations_ = flagValue; @@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "enableBridgelessArchitecture"); + markFlagAsAccessed(17, "enableBridgelessArchitecture"); flagValue = currentProvider_->enableBridgelessArchitecture(); enableBridgelessArchitecture_ = flagValue; @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableCppPropsIteratorSetter"); + markFlagAsAccessed(18, "enableCppPropsIteratorSetter"); flagValue = currentProvider_->enableCppPropsIteratorSetter(); enableCppPropsIteratorSetter_ = flagValue; @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCustomFocusSearchOnClippedElementsAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableCustomFocusSearchOnClippedElementsAndroid"); + markFlagAsAccessed(19, "enableCustomFocusSearchOnClippedElementsAndroid"); flagValue = currentProvider_->enableCustomFocusSearchOnClippedElementsAndroid(); enableCustomFocusSearchOnClippedElementsAndroid_ = flagValue; @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDestroyShadowTreeRevisionAsync() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableDestroyShadowTreeRevisionAsync"); + markFlagAsAccessed(20, "enableDestroyShadowTreeRevisionAsync"); flagValue = currentProvider_->enableDestroyShadowTreeRevisionAsync(); enableDestroyShadowTreeRevisionAsync_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableDoubleMeasurementFixAndroid"); + markFlagAsAccessed(21, "enableDoubleMeasurementFixAndroid"); flagValue = currentProvider_->enableDoubleMeasurementFixAndroid(); enableDoubleMeasurementFixAndroid_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerMainQueueModulesOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enableEagerMainQueueModulesOnIOS"); + markFlagAsAccessed(22, "enableEagerMainQueueModulesOnIOS"); flagValue = currentProvider_->enableEagerMainQueueModulesOnIOS(); enableEagerMainQueueModulesOnIOS_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableEagerRootViewAttachment"); + markFlagAsAccessed(23, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableExclusivePropsUpdateAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableExclusivePropsUpdateAndroid"); + markFlagAsAccessed(24, "enableExclusivePropsUpdateAndroid"); flagValue = currentProvider_->enableExclusivePropsUpdateAndroid(); enableExclusivePropsUpdateAndroid_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableFabricLogs"); + markFlagAsAccessed(25, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableFabricRenderer"); + markFlagAsAccessed(26, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableFontScaleChangesUpdatingLayout"); + markFlagAsAccessed(27, "enableFontScaleChangesUpdatingLayout"); flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout(); enableFontScaleChangesUpdatingLayout_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSTextBaselineOffsetPerLine() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(28, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(29, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(30, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingJNIBatchingAndroid() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableImagePrefetchingJNIBatchingAndroid"); + markFlagAsAccessed(31, "enableImagePrefetchingJNIBatchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingJNIBatchingAndroid(); enableImagePrefetchingJNIBatchingAndroid_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingOnUiThreadAndroid() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableImagePrefetchingOnUiThreadAndroid"); + markFlagAsAccessed(32, "enableImagePrefetchingOnUiThreadAndroid"); flagValue = currentProvider_->enableImagePrefetchingOnUiThreadAndroid(); enableImagePrefetchingOnUiThreadAndroid_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(33, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableImperativeFocus"); + markFlagAsAccessed(34, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(35, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(36, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableKeyEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableKeyEvents"); + markFlagAsAccessed(37, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(38, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(39, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueCoordinatorOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enableMainQueueCoordinatorOnIOS"); + markFlagAsAccessed(40, "enableMainQueueCoordinatorOnIOS"); flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS(); enableMainQueueCoordinatorOnIOS_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(41, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableNativeCSSParsing"); + markFlagAsAccessed(42, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableNetworkEventReporting"); + markFlagAsAccessed(43, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enablePreparedTextLayout"); + markFlagAsAccessed(44, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(45, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(46, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enableViewCulling"); + markFlagAsAccessed(47, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enableViewRecycling"); + markFlagAsAccessed(48, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "enableViewRecyclingForImage"); + markFlagAsAccessed(49, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -920,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(49, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(50, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "enableViewRecyclingForText"); + markFlagAsAccessed(51, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "enableViewRecyclingForView"); + markFlagAsAccessed(52, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewClippingWithoutScrollView // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "enableVirtualViewClippingWithoutScrollViewClipping"); + markFlagAsAccessed(53, "enableVirtualViewClippingWithoutScrollViewClipping"); flagValue = currentProvider_->enableVirtualViewClippingWithoutScrollViewClipping(); enableVirtualViewClippingWithoutScrollViewClipping_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewContainerStateExperimenta // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(54, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewDebugFeatures() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(55, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewRenderState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(55, "enableVirtualViewRenderState"); + markFlagAsAccessed(56, "enableVirtualViewRenderState"); flagValue = currentProvider_->enableVirtualViewRenderState(); enableVirtualViewRenderState_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewWindowFocusDetection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "enableVirtualViewWindowFocusDetection"); + markFlagAsAccessed(57, "enableVirtualViewWindowFocusDetection"); flagValue = currentProvider_->enableVirtualViewWindowFocusDetection(); enableVirtualViewWindowFocusDetection_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::enableWebPerformanceAPIsByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "enableWebPerformanceAPIsByDefault"); + markFlagAsAccessed(58, "enableWebPerformanceAPIsByDefault"); flagValue = currentProvider_->enableWebPerformanceAPIsByDefault(); enableWebPerformanceAPIsByDefault_ = flagValue; @@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(58, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(59, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxAssertSingleHostState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(60, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "fuseboxEnabledRelease"); + markFlagAsAccessed(61, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1136,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(62, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(63, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(64, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "perfIssuesEnabled"); + markFlagAsAccessed(65, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1208,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "perfMonitorV2Enabled"); + markFlagAsAccessed(66, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1226,7 +1244,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "preparedTextCacheSize"); + markFlagAsAccessed(67, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1244,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(68, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1262,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(69, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldSetEnabledBasedOnAccessibilityState( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "shouldSetEnabledBasedOnAccessibilityState"); + markFlagAsAccessed(70, "shouldSetEnabledBasedOnAccessibilityState"); flagValue = currentProvider_->shouldSetEnabledBasedOnAccessibilityState(); shouldSetEnabledBasedOnAccessibilityState_ = flagValue; @@ -1298,7 +1316,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(71, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(72, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(73, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1352,7 +1370,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(74, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1370,7 +1388,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(75, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1388,7 +1406,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(75, "useFabricInterop"); + markFlagAsAccessed(76, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1406,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeEqualsInNativeReadableArrayAndroi // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(76, "useNativeEqualsInNativeReadableArrayAndroid"); + markFlagAsAccessed(77, "useNativeEqualsInNativeReadableArrayAndroid"); flagValue = currentProvider_->useNativeEqualsInNativeReadableArrayAndroid(); useNativeEqualsInNativeReadableArrayAndroid_ = flagValue; @@ -1424,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeTransformHelperAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "useNativeTransformHelperAndroid"); + markFlagAsAccessed(78, "useNativeTransformHelperAndroid"); flagValue = currentProvider_->useNativeTransformHelperAndroid(); useNativeTransformHelperAndroid_ = flagValue; @@ -1442,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(79, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1460,7 +1478,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(79, "useRawPropsJsiValue"); + markFlagAsAccessed(80, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -1478,7 +1496,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(80, "useShadowNodeStateOnClone"); + markFlagAsAccessed(81, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -1496,7 +1514,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "useSharedAnimatedBackend"); + markFlagAsAccessed(82, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1514,7 +1532,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(82, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(83, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1532,7 +1550,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "useTurboModuleInterop"); + markFlagAsAccessed(84, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1550,7 +1568,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "useTurboModules"); + markFlagAsAccessed(85, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1568,7 +1586,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(85, "viewCullingOutsetRatio"); + markFlagAsAccessed(86, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1586,7 +1604,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewHysteresisRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(86, "virtualViewHysteresisRatio"); + markFlagAsAccessed(87, "virtualViewHysteresisRatio"); flagValue = currentProvider_->virtualViewHysteresisRatio(); virtualViewHysteresisRatio_ = flagValue; @@ -1604,7 +1622,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(87, "virtualViewPrerenderRatio"); + markFlagAsAccessed(88, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 232a911e3327..d1f4ccdc02e1 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -46,6 +46,7 @@ class ReactNativeFeatureFlagsAccessor { bool disableViewPreallocationAndroid(); bool enableAccessibilityOrder(); bool enableAccumulatedUpdatesInRawPropsAndroid(); + bool enableAndroidAntialiasedBorderRadiusClipping(); bool enableAndroidLinearText(); bool enableAndroidTextMeasurementOptimizations(); bool enableBridgelessArchitecture(); @@ -131,7 +132,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 88> accessedFeatureFlags_; + std::array, 89> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -147,6 +148,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> disableViewPreallocationAndroid_; std::atomic> enableAccessibilityOrder_; std::atomic> enableAccumulatedUpdatesInRawPropsAndroid_; + std::atomic> enableAndroidAntialiasedBorderRadiusClipping_; std::atomic> enableAndroidLinearText_; std::atomic> enableAndroidTextMeasurementOptimizations_; std::atomic> enableBridgelessArchitecture_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 15e355fad3e6..5fea80bf7243 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<18c966119a9b6123aea3b088e0eaf98b>> + * @generated SignedSource<> */ /** @@ -83,6 +83,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableAndroidAntialiasedBorderRadiusClipping() override { + return false; + } + bool enableAndroidLinearText() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 44d556c17054..420a87b5d01b 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<152ea11685f3770782035b08831ef04d>> + * @generated SignedSource<> */ /** @@ -171,6 +171,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::enableAccumulatedUpdatesInRawPropsAndroid(); } + bool enableAndroidAntialiasedBorderRadiusClipping() override { + auto value = values_["enableAndroidAntialiasedBorderRadiusClipping"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::enableAndroidAntialiasedBorderRadiusClipping(); + } + bool enableAndroidLinearText() override { auto value = values_["enableAndroidLinearText"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 92f1046cfcfb..34b7ef17023b 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<2fe890d6419dc1aaa9aa2d69a6e96bed>> + * @generated SignedSource<<3e8df9a7ff492fee6b5755c1691e150c>> */ /** @@ -39,6 +39,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool disableViewPreallocationAndroid() = 0; virtual bool enableAccessibilityOrder() = 0; virtual bool enableAccumulatedUpdatesInRawPropsAndroid() = 0; + virtual bool enableAndroidAntialiasedBorderRadiusClipping() = 0; virtual bool enableAndroidLinearText() = 0; virtual bool enableAndroidTextMeasurementOptimizations() = 0; virtual bool enableBridgelessArchitecture() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 217325d8b111..0f534106be3f 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<3235f8d2413da4e9f10c7d8ff78bfeb8>> + * @generated SignedSource<<0cdf0b920d8c8a083781028ff0490bf3>> */ /** @@ -114,6 +114,11 @@ bool NativeReactNativeFeatureFlags::enableAccumulatedUpdatesInRawPropsAndroid( return ReactNativeFeatureFlags::enableAccumulatedUpdatesInRawPropsAndroid(); } +bool NativeReactNativeFeatureFlags::enableAndroidAntialiasedBorderRadiusClipping( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableAndroidAntialiasedBorderRadiusClipping(); +} + bool NativeReactNativeFeatureFlags::enableAndroidLinearText( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableAndroidLinearText(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 93f43150f00b..5fa5c6c7c303 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<9a7d4159c54f9ccc3e0d3cc461b66b7e>> + * @generated SignedSource<> */ /** @@ -64,6 +64,8 @@ class NativeReactNativeFeatureFlags bool enableAccumulatedUpdatesInRawPropsAndroid(jsi::Runtime& runtime); + bool enableAndroidAntialiasedBorderRadiusClipping(jsi::Runtime& runtime); + bool enableAndroidLinearText(jsi::Runtime& runtime); bool enableAndroidTextMeasurementOptimizations(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 692b9f8a3ed7..3f45a7a4c97a 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -201,6 +201,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + enableAndroidAntialiasedBorderRadiusClipping: { + defaultValue: false, + metadata: { + dateAdded: '2025-01-31', + description: + 'Enable antialiased border radius clipping for Android API 28 and below using manual masking with Porter-Duff compositing', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableAndroidLinearText: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index ece2e0be4485..2080e87d5b81 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<312e7dcaaaf8bade0acf80d15e8eedee>> + * @generated SignedSource<> * @flow strict * @noformat */ @@ -65,6 +65,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ disableViewPreallocationAndroid: Getter, enableAccessibilityOrder: Getter, enableAccumulatedUpdatesInRawPropsAndroid: Getter, + enableAndroidAntialiasedBorderRadiusClipping: Getter, enableAndroidLinearText: Getter, enableAndroidTextMeasurementOptimizations: Getter, enableBridgelessArchitecture: Getter, @@ -281,6 +282,10 @@ export const enableAccessibilityOrder: Getter = createNativeFlagGetter( * When enabled, Android will accumulate updates in rawProps to reduce the number of mounting instructions for cascading re-renders. */ export const enableAccumulatedUpdatesInRawPropsAndroid: Getter = createNativeFlagGetter('enableAccumulatedUpdatesInRawPropsAndroid', false); +/** + * Enable antialiased border radius clipping for Android API 28 and below using manual masking with Porter-Duff compositing + */ +export const enableAndroidAntialiasedBorderRadiusClipping: Getter = createNativeFlagGetter('enableAndroidAntialiasedBorderRadiusClipping', false); /** * Enables linear text rendering on Android wherever subpixel text rendering is enabled */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 3c3bb117ed3b..7d181d45c752 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<0de9df853ee6af976b4e15f55e6b9b26>> * @flow strict * @noformat */ @@ -39,6 +39,7 @@ export interface Spec extends TurboModule { +disableViewPreallocationAndroid?: () => boolean; +enableAccessibilityOrder?: () => boolean; +enableAccumulatedUpdatesInRawPropsAndroid?: () => boolean; + +enableAndroidAntialiasedBorderRadiusClipping?: () => boolean; +enableAndroidLinearText?: () => boolean; +enableAndroidTextMeasurementOptimizations?: () => boolean; +enableBridgelessArchitecture?: () => boolean;