Skip to content

Commit

Permalink
Revert "Reland: Enforce the rule of calling FlutterView.Render (flutt…
Browse files Browse the repository at this point in the history
…er#45300)" (flutter#46919)

Reverts flutter#45555 due to possible performance regression, b/304898239
  • Loading branch information
dkwingsmt authored and Casey Hillers committed Oct 18, 2023
1 parent d00fabf commit ca16e90
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 370 deletions.
42 changes: 0 additions & 42 deletions lib/ui/fixtures/ui_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1076,45 +1076,3 @@ external void _callHook(
Object? arg20,
Object? arg21,
]);

Scene _createRedBoxScene(Size size) {
final SceneBuilder builder = SceneBuilder();
builder.pushOffset(0.0, 0.0);
final Paint paint = Paint()
..color = Color.fromARGB(255, 255, 0, 0)
..style = PaintingStyle.fill;
final PictureRecorder baseRecorder = PictureRecorder();
final Canvas canvas = Canvas(baseRecorder);
canvas.drawRect(Rect.fromLTRB(0.0, 0.0, size.width, size.height), paint);
final Picture picture = baseRecorder.endRecording();
builder.addPicture(Offset(0.0, 0.0), picture);
builder.pop();
return builder.build();
}

@pragma('vm:entry-point')
void incorrectImmediateRender() {
PlatformDispatcher.instance.views.first.render(_createRedBoxScene(Size(2, 2)));
_finish();
// Don't schedule a frame here. This test only checks if the
// [FlutterView.render] call is propagated to PlatformConfiguration.render
// and thus doesn't need anything from `Animator` or `Engine`, which,
// besides, are not even created in the native side at all.
}

@pragma('vm:entry-point')
void incorrectDoubleRender() {
PlatformDispatcher.instance.onBeginFrame = (Duration value) {
PlatformDispatcher.instance.views.first.render(_createRedBoxScene(Size(2, 2)));
PlatformDispatcher.instance.views.first.render(_createRedBoxScene(Size(3, 3)));
};
PlatformDispatcher.instance.onDrawFrame = () {
PlatformDispatcher.instance.views.first.render(_createRedBoxScene(Size(4, 4)));
PlatformDispatcher.instance.views.first.render(_createRedBoxScene(Size(5, 5)));
};
_finish();
// Don't schedule a frame here. This test only checks if the
// [FlutterView.render] call is propagated to PlatformConfiguration.render
// and thus doesn't need anything from `Animator` or `Engine`, which,
// besides, are not even created in the native side at all.
}
33 changes: 0 additions & 33 deletions lib/ui/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -308,21 +308,6 @@ class PlatformDispatcher {
_invoke(onMetricsChanged, _onMetricsChangedZone);
}

// [FlutterView]s for which [FlutterView.render] has already been called
// during the current [onBeginFrame]/[onDrawFrame] callback sequence.
//
// The field is null outside the scope of those callbacks indicating that
// calls to [FlutterView.render] must be ignored. Furthermore, if a given
// [FlutterView] is already present in this set when its [FlutterView.render]
// is called again, that call must be ignored as a duplicate.
//
// Between [onBeginFrame] and [onDrawFrame] the properties value is
// temporarily stored in `_renderedViewsBetweenCallbacks` so that it survives
// the gap between the two callbacks.
Set<FlutterView>? _renderedViews;
// Temporary storage of the `_renderedViews` value between `_beginFrame` and
// `_drawFrame`.
Set<FlutterView>? _renderedViewsBetweenCallbacks;

/// A callback invoked when any view begins a frame.
///
Expand All @@ -344,20 +329,11 @@ class PlatformDispatcher {

// Called from the engine, via hooks.dart
void _beginFrame(int microseconds) {
assert(_renderedViews == null);
assert(_renderedViewsBetweenCallbacks == null);

_renderedViews = <FlutterView>{};
_invoke1<Duration>(
onBeginFrame,
_onBeginFrameZone,
Duration(microseconds: microseconds),
);
_renderedViewsBetweenCallbacks = _renderedViews;
_renderedViews = null;

assert(_renderedViews == null);
assert(_renderedViewsBetweenCallbacks != null);
}

/// A callback that is invoked for each frame after [onBeginFrame] has
Expand All @@ -375,16 +351,7 @@ class PlatformDispatcher {

// Called from the engine, via hooks.dart
void _drawFrame() {
assert(_renderedViews == null);
assert(_renderedViewsBetweenCallbacks != null);

_renderedViews = _renderedViewsBetweenCallbacks;
_renderedViewsBetweenCallbacks = null;
_invoke(onDrawFrame, _onDrawFrameZone);
_renderedViews = null;

assert(_renderedViews == null);
assert(_renderedViewsBetweenCallbacks == null);
}

/// A callback that is invoked when pointer data is available.
Expand Down
28 changes: 7 additions & 21 deletions lib/ui/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -327,21 +327,14 @@ class FlutterView {

/// Updates the view's rendering on the GPU with the newly provided [Scene].
///
/// ## Requirement for calling this method
///
/// This method must be called within the synchronous scope of the
/// This function must be called within the scope of the
/// [PlatformDispatcher.onBeginFrame] or [PlatformDispatcher.onDrawFrame]
/// callbacks. Calls out of this scope will be ignored. To use this method,
/// create a callback that calls this method instead, and assign it to either
/// of the fields above; then schedule a frame, which is done typically with
/// [PlatformDispatcher.scheduleFrame]. Also, make sure the callback does not
/// have `await` before the `FlutterWindow.render` call.
///
/// Additionally, this method can only be called once for each view during a
/// single [PlatformDispatcher.onBeginFrame]/[PlatformDispatcher.onDrawFrame]
/// callback sequence. Duplicate calls will be ignored in production.
/// callbacks being invoked.
///
/// ## How to record a scene
/// If this function is called a second time during a single
/// [PlatformDispatcher.onBeginFrame]/[PlatformDispatcher.onDrawFrame]
/// callback sequence or called outside the scope of those callbacks, the call
/// will be ignored.
///
/// To record graphical operations, first create a [PictureRecorder], then
/// construct a [Canvas], passing that [PictureRecorder] to its constructor.
Expand All @@ -360,14 +353,7 @@ class FlutterView {
/// scheduling of frames.
/// * [RendererBinding], the Flutter framework class which manages layout and
/// painting.
void render(Scene scene) {
if (platformDispatcher._renderedViews?.add(this) != true) {
// Duplicated calls or calls outside of onBeginFrame/onDrawFrame
// (indicated by _renderedViews being null) are ignored, as documented.
return;
}
_render(scene as _NativeScene);
}
void render(Scene scene) => _render(scene as _NativeScene);

@Native<Void Function(Pointer<Void>)>(symbol: 'PlatformConfigurationNativeApi::Render')
external static void _render(_NativeScene scene);
Expand Down
Loading

0 comments on commit ca16e90

Please sign in to comment.