Skip to content

Conversation

@liyuqian
Copy link
Contributor

@liyuqian liyuqian commented Aug 14, 2019

Without this, developers have to override onReportTimings to listen for FrameTiming.
That can potentially break previous onReportTimings listeners if they forget to call
the old listener in their new callback.

This change would make it safer and more convenient to listen for FrameTiming
(as illustrated in the removed TODO).

The following unit tests (and many other driver tests) covered this change:

  • Flutter.Frame event fired
  • All tests in service_extensions_test.dart (due to setUpAll)

@fluttergithubbot fluttergithubbot added the framework flutter/packages/flutter repository. See also f: labels. label Aug 14, 2019
@liyuqian liyuqian changed the title [wip] Add a broadcast stream for FrameTiming Add a broadcast stream for FrameTiming Aug 15, 2019
@liyuqian liyuqian added the c: performance Relates to speed or footprint issues (see "perf:" labels) label Aug 15, 2019
Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

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

Maybe add a slightly more detailed PR description for future archeologists: Why this change? Is it just fixing the TODO? Is there an issue where somebody was asking for this to be exposed, etc.

final TimingsCallback oldCallback = WidgetsBinding.instance.window.onReportTimings;
WidgetsBinding.instance.window.onReportTimings = (List<FrameTiming> timings) {
StreamSubscription<FrameTiming> firstFrameSubscription;
firstFrameSubscription = WidgetsBinding.instance.frameTimingStream.listen((FrameTiming timing) {
Copy link
Member

Choose a reason for hiding this comment

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

Would Stream.first be appropriate here since you cancel the stream after you get the first even right away?

https://master-api.flutter.dev/flutter/dart-async/Stream/first.html

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added more details to the PR description.

Also added test which verifies that the broadcast stream won't be shut down (cancelled) by Stream.first. (Stream.first will only cancel its own subscription, and leave other subscription still running.)

Copy link
Member

Choose a reason for hiding this comment

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

So, we should be able to use it here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. Thanks!

Copy link
Contributor

@devoncarew devoncarew left a comment

Choose a reason for hiding this comment

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

(I thought I'd sent these comments earlier in the day, but noticed they were still pending)

int _frameTimingListenCount = 0;

void _onFrameTimingListen() {
_frameTimingListenCount += 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe that StreamController maintains this count for you - onListen is called when the first listener is added, and onCancel is called when the last listener unsubscribes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I misread the API doc. Removing my counter.

_frameTimingListenCount -= 1;
assert(_frameTimingListenCount >= 0);
if (_frameTimingListenCount == 0) {
window.onReportTimings = _oldTimingsCallback;
Copy link
Contributor

Choose a reason for hiding this comment

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

Trying to restore the _oldTimingsCallback is problematic - we don't know if anybody else has changed window.onReportTimings in the meantime, or is similarly trying to manage that field.

A solution w/o that issue would be to have onReportTimings be more of an implementation detail in dart:ui Window, and that that class itself to expose a broadcast stream. Otherwise things get complicated if we have more than one consumer that wants the frame timing info.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd love to do that. Would that be a breaking change as we're removing onReportTimings and only expose this broadcast stream from dart:ui Window?

Copy link
Contributor

Choose a reason for hiding this comment

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

It would be, but I think the only use of the API is in package:flutter itself. The breaking change process would be a good way to find any additional usages, and to let people who are using it know how to migrate to the new API (which would be a straightforward migration).

@liyuqian
Copy link
Contributor Author

Close this in favor of flutter/engine#11041

We'll open a new framework PR once that engine PR lands to re-apply the stream listening and test change in this PR.

@liyuqian liyuqian closed this Aug 15, 2019
liyuqian added a commit to flutter/engine that referenced this pull request Aug 19, 2019
Without this, developers have to override `onReportTimings` to listen for `FrameTiming`.
That can potentially break previous `onReportTimings` listeners if they forget to call
the old listener in their new callback.

This PR replaces the similar RP in the framework: flutter/flutter#38574

Once this PR landed, we'll have to create another framework PR to use the stream to replace
`onReportTimings` usages.

Once that's done, we can then propose the breaking change of removing the deprecated
`onReportTimings`.
liyuqian added a commit that referenced this pull request Aug 28, 2019
This is the continuation of flutter/engine#11041 and #38574

This is not a breaking change as we're not removing `onReportTimings` API.
We're simply removing the use of it in our framework.
@liyuqian liyuqian deleted the broadcast branch September 9, 2019 18:21
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

c: performance Relates to speed or footprint issues (see "perf:" labels) framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants