Skip to content

[Android] Fix 1px edge clipping on Platform Views by preserving floating-point precision where possible and rounding otherwise instead of truncating - #190311

Merged
auto-submit[bot] merged 10 commits into
flutter:masterfrom
gmackall:platform-view-float-precision
Aug 19, 2026

Conversation

@gmackall

@gmackall gmackall commented Jul 30, 2026 •

Copy link
Copy Markdown
Member

Fixes #189834

It's kind of hard to see in the screenshots that Android studio device mirroring produces, but there's a 1px green border of the underlay box visible pre-change clearly on device. You can kind of see it if you click the screenshot and zoom in.

Golden test screenshots:

Unclipped Clipped
Pre-change Pre-change Unclipped Pre-change Clipped
Post-change Post-change Unclipped Post-change Clipped

Ai description of the changes, which is accurate (i checked)

On Android devices with a fractional Device Pixel Ratio (dpr, e.g., 2.625 on 420dpi screens), converting between logical and physical pixels in floating point often yields values just below a whole integer (e.g., 1080 / 2.625 * 2.625 = 1079.999965). Previously, the C++ Engine and Java embedding truncated these values to integers (static_cast<int32_t> / (int)), systematically shaving 1 physical pixel off the right and bottom edges of Platform Views, clip rectangles, and texture buffer sizes. This left a visible 1px line of underlying background content around the view.

This PR fixes precision loss across three equivalence classes in the Android Platform View composition pipeline:

1. Plumb floating-point precision where native APIs accept floats (RectF / MethodChannel)

  • Mutator Stack Clipping: Updated pushClipRect and pushClipRRect in C++ JNI (platform_view_android_jni_impl.cc) and Java (FlutterMutatorsStack.java) from integer (IIII)V to floating-point (FFFF)V, storing RectF and passing floats directly to Android Path.addRect(RectF).
  • Buffer Size Reporting: Updated PlatformViewBufferSize width/height from int to double and changed toLogicalPixels(double) in (PlatformViewsController.java) to return fractional double values without integer casting or rounding.

2. Round onto the integer grid where Android APIs require integers

  • View Layout & Sizing: In C++ (external_view_embedder.cc and external_view_embedder_2.cc), replaced integer truncation with rounding:
    • View bounding boxes use DlIRect::Round(GetViewRect(...)).
    • Physical width/height conversion uses std::round(size_points * dpr) via ToPhysicalPixels(...).

3. Sizing & Buffer Reporting by Composition Mode (PlatformViewsController.java)

  • Virtual Display Mode: Directly reports the requested logical dimensions (request.newLogicalWidth, request.newLogicalHeight), bypassing physical-to-logical round-trip conversion entirely.
  • Texture Layer Hybrid Composition (TLHC): Because TLHC render targets only grow and never shrink, the controller reports the actual unshrunk physical render target size as an exact fractional double (physicalPixels / getDisplayDensity()). This allows the framework to size the texture 1:1 and clip it to the widget rather than scaling it down.

Testing

@github-actions github-actions Bot added platform-android Android applications specifically engine flutter/engine related. See also e: labels. team-android Owned by Android platform team labels Jul 30, 2026
@gmackall gmackall added the CICD Run CI/CD label Jul 30, 2026
@gmackall
gmackall marked this pull request as ready for review July 30, 2026 21:30
@gmackall
gmackall requested a review from a team as a code owner July 30, 2026 21:30
@gmackall
gmackall requested review from jesswrd and removed request for a team July 30, 2026 21:30

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modifies the Android platform view embedder to use floating-point values instead of integers for layout and clipping bounds, preventing truncation artifacts on fractional pixel boundaries. Sizing conversions now use rounding instead of truncation, and the mutators stack has been updated to support fractional clip rects. New integration and unit tests are introduced to verify these changes. Feedback on the changes suggests adding a defensive guard in PlatformViewsController.java to prevent a potential division by zero when calculating logical pixels.

@gmackall
gmackall requested a review from mboetger July 30, 2026 21:56
@gmackall gmackall changed the title [Android] Fix 1px edge clipping on Platform Views by preserving floating-point and rounding precision [Android] Fix 1px edge clipping on Platform Views by preserving floating-point precision where possible and rounding otherwise instead of truncating Jul 30, 2026
/// The size of the platform view, in *physical* pixels.
///
/// Deliberately not a whole number of pixels. Android view geometry is
/// integral, so the engine has to snap this to the pixel grid; if it truncates

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: took me too long to realize you were using this to mean "Android view geometry uses integers". At least that what I think you're saying :)

@mboetger mboetger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gmackall gmackall added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 18, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 18, 2026
@auto-submit

auto-submit Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/190311, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@gmackall gmackall added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 19, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 19, 2026
@auto-submit

auto-submit Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/190311, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

@gmackall gmackall added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 19, 2026
@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Aug 19, 2026
@auto-submit

auto-submit Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/190311, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD engine flutter/engine related. See also e: labels. platform-android Android applications specifically team-android Owned by Android platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Android WebViewWidget shows a thin line from Scaffold background on the right edge

3 participants