Skip to content

Fix image disappearing on Nougat with antialiased border radius clipping#55527

Open
Abbondanzo wants to merge 1 commit intofacebook:mainfrom
Abbondanzo:export-D92980234
Open

Fix image disappearing on Nougat with antialiased border radius clipping#55527
Abbondanzo wants to merge 1 commit intofacebook:mainfrom
Abbondanzo:export-D92980234

Conversation

@Abbondanzo
Copy link
Contributor

Summary:
On API 24 (Nougat), the DST_OUT + EVEN_ODD inverse path technique in clipWithAntiAliasing() doesn't render correctly — it erases all image content instead of just the area outside the rounded rect.

The bug manifests specifically with ReactImageView (Fresco-backed) but not plain ImageView. ReactImageView's Fresco hierarchy configures RoundingParams.RoundingMethod.BITMAP_ONLY, which causes the drawable chain to draw through a BitmapShader-based paint. This shader-based drawing interacts badly with the EVEN_ODD fill + DST_OUT compositing inside a hardware-accelerated saveLayer on API 24's Skia renderer.

The fix replaces the EVEN_ODD + DST_OUT technique with a nested saveLayer using DST_IN compositing, following the same pattern used by Facebook's Keyframes library (AbstractLayer.applyClip). The mask shape is drawn into a separate layer; when restored with DST_IN, content is preserved only where the mask is opaque. A drawColor(CLEAR) call after saveLayer ensures the layer starts fully transparent — without this, on API 24, the layer may retain parent content, causing DST_IN to see non-zero alpha everywhere and clip nothing.

Changelog: [Android][Fixed] - Fix image content disappearing on API 24 (Nougat) when antialiased border radius clipping is applied

Differential Revision: D92980234

Summary:
On API 24 (Nougat), the `DST_OUT` + `EVEN_ODD` inverse path technique in `clipWithAntiAliasing()` doesn't render correctly — it erases all image content instead of just the area outside the rounded rect.

The bug manifests specifically with ReactImageView (Fresco-backed) but not plain ImageView. ReactImageView's Fresco hierarchy configures `RoundingParams.RoundingMethod.BITMAP_ONLY`, which causes the drawable chain to draw through a `BitmapShader`-based paint. This shader-based drawing interacts badly with the `EVEN_ODD` fill + `DST_OUT` compositing inside a hardware-accelerated `saveLayer` on API 24's Skia renderer. 

The fix replaces the `EVEN_ODD` + `DST_OUT` technique with a nested `saveLayer` using `DST_IN` compositing, following the same pattern used by Facebook's Keyframes library (`AbstractLayer.applyClip`). The mask shape is drawn into a separate layer; when restored with `DST_IN`, content is preserved only where the mask is opaque. A `drawColor(CLEAR)` call after `saveLayer` ensures the layer starts fully transparent — without this, on API 24, the layer may retain parent content, causing `DST_IN` to see non-zero alpha everywhere and clip nothing.

Changelog: [Android][Fixed] - Fix image content disappearing on API 24 (Nougat) when antialiased border radius clipping is applied

Differential Revision: D92980234
@meta-codesync
Copy link

meta-codesync bot commented Feb 11, 2026

@Abbondanzo has exported this pull request. If you are a Meta employee, you can view the originating Diff in D92980234.

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants