Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@FelixZhang00
Copy link
Contributor

Fix #29777
we listen for Vsync callback on the UI thread directly, It will save time when the platform thread's MessageQueue is busy.
To implement this, we call Looper.prepare and Looper.run in MessageLoopAndroid::Run through JNI, so we can receive Choreographer's FrameCallback in the UI thread.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@FelixZhang00
Copy link
Contributor Author

Here's the flutter_gallery__transitions_perf benchmark report on a MI 6 phone.
Because the platform thread of the flutter application is not busy, there is no obvious optimization in the benchmark report

BEFORE 

 "average_frame_build_time_millis": 5.831353982300886,
  "90th_percentile_frame_build_time_millis": 11.726,
  "99th_percentile_frame_build_time_millis": 21.811,
  "worst_frame_build_time_millis": 165.693,
  "missed_frame_build_budget_count": 16,
  "average_frame_rasterizer_time_millis": 14.67524944812361,
  "90th_percentile_frame_rasterizer_time_millis": 17.805,
  "99th_percentile_frame_rasterizer_time_millis": 37.69,
  "worst_frame_rasterizer_time_millis": 152.432,
  "missed_frame_rasterizer_budget_count": 97,
  "frame_count": 452,
  "frame_rasterizer_count": 453,



AFTER


  "average_frame_build_time_millis": 5.82446436285097,
  "90th_percentile_frame_build_time_millis": 11.55,
  "99th_percentile_frame_build_time_millis": 24.427,
  "worst_frame_build_time_millis": 163.288,
  "missed_frame_build_budget_count": 20,
  "average_frame_rasterizer_time_millis": 14.526374458874466,
  "90th_percentile_frame_rasterizer_time_millis": 18.337,
  "99th_percentile_frame_rasterizer_time_millis": 38.931,
  "worst_frame_rasterizer_time_millis": 145.733,
  "missed_frame_rasterizer_budget_count": 82,
  "frame_count": 463,
  "frame_rasterizer_count": 462,

@FelixZhang00
Copy link
Contributor Author

FelixZhang00 commented Nov 23, 2021

Another benchmark report on the same device, but I create a busyTask on platform manually.
We can see the obvious optimization

Before

  "average_frame_build_time_millis": 9.40737745098039,
  "90th_percentile_frame_build_time_millis": 17.377,
  "99th_percentile_frame_build_time_millis": 35.249,
  "worst_frame_build_time_millis": 158.561,
  "missed_frame_build_budget_count": 27,
  "average_frame_rasterizer_time_millis": 20.904769607843143,
  "90th_percentile_frame_rasterizer_time_millis": 31.023,
  "99th_percentile_frame_rasterizer_time_millis": 60.068,
  "worst_frame_rasterizer_time_millis": 118.157,
  "missed_frame_rasterizer_budget_count": 107,
  "frame_count": 204,
  "frame_rasterizer_count": 204,


After

 "average_frame_build_time_millis": 6.075204899777277,
  "90th_percentile_frame_build_time_millis": 12.187,
  "99th_percentile_frame_build_time_millis": 27.465,
  "worst_frame_build_time_millis": 170.334,
  "missed_frame_build_budget_count": 20,
  "average_frame_rasterizer_time_millis": 14.731560267857137,
  "90th_percentile_frame_rasterizer_time_millis": 18.493,
  "99th_percentile_frame_rasterizer_time_millis": 40.072,
  "worst_frame_rasterizer_time_millis": 120.032,
  "missed_frame_rasterizer_budget_count": 78,
  "frame_count": 449,
  "frame_rasterizer_count": 448,

the busyTask code

  private static void runBusyTask(){
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            runBusyTask();
        }
    });
}

@ColdPaleLight ColdPaleLight changed the base branch from master to main November 23, 2021 13:40
Copy link
Member

@chinmaygarde chinmaygarde left a comment

Choose a reason for hiding this comment

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

Excellent. This brings Android behavior in line with iOS too. And yeah, existing benchmarks won't show improvements because their main threads don't service blocking code.

@ColdPaleLight
Copy link
Member

This LGTM once it LGT @dnfield

@dnfield
Copy link
Contributor

dnfield commented Nov 24, 2021

Can you add some documentation to FlutterJNI#asyncWaitForVsync and the related delegate to mention that it is not called from the platform thread?

@FelixZhang00
Copy link
Contributor Author

Can you add some documentation to FlutterJNI#asyncWaitForVsync and the related delegate to mention that it is not called from the platform thread?

done

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

Labels

cla: yes needs tests platform-android waiting for tree to go green This PR is approved and tested, but waiting for the tree to be green to land.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants