Skip to content

Commit 4b76ac4

Browse files
authored
[CP] [skwasm] Fix platform view placement. (flutter#54870)
Cherry-pick of flutter#53845
1 parent a4777ff commit 4b76ac4

File tree

5 files changed

+82
-60
lines changed

5 files changed

+82
-60
lines changed

lib/web_ui/lib/src/engine/layers.dart

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -352,14 +352,14 @@ class ShaderMaskOperation implements LayerOperation {
352352
}
353353

354354
class PlatformView {
355-
PlatformView(this.viewId, this.size, this.styling);
355+
PlatformView(this.viewId, this.bounds, this.styling);
356356

357-
int viewId;
357+
final int viewId;
358358

359359
// The bounds of this platform view, in the layer's local coordinate space.
360-
ui.Size size;
360+
final ui.Rect bounds;
361361

362-
PlatformViewStyling styling;
362+
final PlatformViewStyling styling;
363363
}
364364

365365
sealed class LayerSlice {
@@ -570,20 +570,8 @@ class LayerBuilder {
570570

571571
PlatformViewStyling? _memoizedPlatformViewStyling;
572572

573-
PlatformViewStyling _createPlatformViewStyling() {
574-
final PlatformViewStyling? innerStyling = operation?.createPlatformViewStyling();
575-
final PlatformViewStyling? outerStyling = parent?.platformViewStyling;
576-
if (innerStyling == null) {
577-
return outerStyling ?? const PlatformViewStyling();
578-
}
579-
if (outerStyling == null) {
580-
return innerStyling;
581-
}
582-
return PlatformViewStyling.combine(outerStyling, innerStyling);
583-
}
584-
585573
PlatformViewStyling get platformViewStyling {
586-
return _memoizedPlatformViewStyling ??= _createPlatformViewStyling();
574+
return _memoizedPlatformViewStyling ??= operation?.createPlatformViewStyling() ?? const PlatformViewStyling();
587575
}
588576

589577
(ui.PictureRecorder, SceneCanvas) _createRecorder(ui.Rect rect) {
@@ -677,16 +665,7 @@ class LayerBuilder {
677665
}) {
678666
final ui.Rect bounds = ui.Rect.fromLTWH(offset.dx, offset.dy, width, height);
679667
platformViewRect = platformViewRect?.expandToInclude(bounds) ?? bounds;
680-
final PlatformViewStyling layerStyling = platformViewStyling;
681-
final PlatformViewStyling viewStyling = offset == ui.Offset.zero
682-
? layerStyling
683-
: PlatformViewStyling.combine(
684-
layerStyling,
685-
PlatformViewStyling(
686-
position: PlatformViewPosition.offset(offset),
687-
),
688-
);
689-
pendingPlatformViews.add(PlatformView(viewId, ui.Size(width, height), viewStyling));
668+
pendingPlatformViews.add(PlatformView(viewId, bounds, platformViewStyling));
690669
}
691670

692671
void mergeLayer(PictureEngineLayer layer) {
@@ -702,7 +681,15 @@ class LayerBuilder {
702681
if (occlusionRect != null) {
703682
platformViewRect = platformViewRect?.expandToInclude(occlusionRect) ?? occlusionRect;
704683
}
705-
pendingPlatformViews.addAll(slice.views);
684+
for (final PlatformView view in slice.views) {
685+
// Merge the platform view styling of this layer with the nested
686+
// platform views.
687+
final PlatformViewStyling styling = PlatformViewStyling.combine(
688+
platformViewStyling,
689+
view.styling,
690+
);
691+
pendingPlatformViews.add(PlatformView(view.viewId, view.bounds, styling));
692+
}
706693
}
707694
}
708695
}

lib/web_ui/lib/src/engine/scene_view.dart

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class EngineSceneView {
179179
}
180180
}
181181
container ??= PlatformViewContainer(view.viewId);
182-
container.size = view.size;
182+
container.bounds = view.bounds;
183183
container.styling = view.styling;
184184
container.updateContents();
185185
newContainers.add(container);
@@ -281,7 +281,7 @@ final class PlatformViewContainer extends SliceContainer {
281281

282282
final int viewId;
283283
PlatformViewStyling? _styling;
284-
ui.Size? _size;
284+
ui.Rect? _bounds;
285285
bool _dirty = false;
286286

287287
@override
@@ -294,9 +294,9 @@ final class PlatformViewContainer extends SliceContainer {
294294
}
295295
}
296296

297-
set size(ui.Size size) {
298-
if (_size != size) {
299-
_size = size;
297+
set bounds(ui.Rect bounds) {
298+
if (_bounds != bounds) {
299+
_bounds = bounds;
300300
_dirty = true;
301301
}
302302
}
@@ -305,23 +305,28 @@ final class PlatformViewContainer extends SliceContainer {
305305
@override
306306
void updateContents() {
307307
assert(_styling != null);
308-
assert(_size != null);
308+
assert(_bounds != null);
309309
if (_dirty) {
310310
final DomCSSStyleDeclaration style = container.style;
311311
final double devicePixelRatio = EngineFlutterDisplay.instance.devicePixelRatio;
312-
final double logicalWidth = _size!.width / devicePixelRatio;
313-
final double logicalHeight = _size!.height / devicePixelRatio;
312+
final double logicalWidth = _bounds!.width / devicePixelRatio;
313+
final double logicalHeight = _bounds!.height / devicePixelRatio;
314314
style.width = '${logicalWidth}px';
315315
style.height = '${logicalHeight}px';
316316
style.position = 'absolute';
317317

318-
final ui.Offset? offset = _styling!.position.offset;
319-
final double logicalLeft = (offset?.dx ?? 0) / devicePixelRatio;
320-
final double logicalTop = (offset?.dy ?? 0) / devicePixelRatio;
318+
final PlatformViewPosition position = PlatformViewPosition.combine(
319+
_styling!.position,
320+
PlatformViewPosition.offset(_bounds!.topLeft),
321+
);
322+
323+
final ui.Offset offset = position.offset ?? ui.Offset.zero;
324+
final double logicalLeft = offset.dx / devicePixelRatio;
325+
final double logicalTop = offset.dy / devicePixelRatio;
321326
style.left = '${logicalLeft}px';
322327
style.top = '${logicalTop}px';
323328

324-
final Matrix4? transform = _styling!.position.transform;
329+
final Matrix4? transform = position.transform;
325330
style.transform = transform != null ? float64ListToCssTransform3d(transform.storage) : '';
326331
style.opacity = _styling!.opacity != 1.0 ? '${_styling!.opacity}' : '';
327332
// TODO(jacksongardner): Implement clip styling for platform views

lib/web_ui/test/engine/scene_builder_test.dart

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,7 @@ void testMain() {
7272
expect(slices.length, 2);
7373
expect(slices[0], pictureSliceWithRect(pictureRect));
7474
expect(slices[1], platformViewSliceWithViews(<PlatformView>[
75-
PlatformView(1, platformViewRect.size, PlatformViewStyling(
76-
position: PlatformViewPosition.offset(platformViewRect.topLeft)
77-
))
75+
PlatformView(1, platformViewRect, const PlatformViewStyling())
7876
]));
7977
});
8078

@@ -95,9 +93,7 @@ void testMain() {
9593
final List<LayerSlice> slices = scene.rootLayer.slices;
9694
expect(slices.length, 2);
9795
expect(slices[0], platformViewSliceWithViews(<PlatformView>[
98-
PlatformView(1, platformViewRect.size, PlatformViewStyling(
99-
position: PlatformViewPosition.offset(platformViewRect.topLeft)
100-
))
96+
PlatformView(1, platformViewRect, const PlatformViewStyling())
10197
]));
10298
expect(slices[1], pictureSliceWithRect(pictureRect));
10399
});
@@ -122,9 +118,7 @@ void testMain() {
122118
expect(slices.length, 3);
123119
expect(slices[0], pictureSliceWithRect(pictureRect1));
124120
expect(slices[1], platformViewSliceWithViews(<PlatformView>[
125-
PlatformView(1, platformViewRect.size, PlatformViewStyling(
126-
position: PlatformViewPosition.offset(platformViewRect.topLeft)
127-
))
121+
PlatformView(1, platformViewRect, const PlatformViewStyling())
128122
]));
129123
expect(slices[2], pictureSliceWithRect(pictureRect2));
130124
});
@@ -153,9 +147,7 @@ void testMain() {
153147
expect(slices.length, 2);
154148
expect(slices[0], pictureSliceWithRect(const ui.Rect.fromLTRB(50, 50, 200, 200)));
155149
expect(slices[1], platformViewSliceWithViews(<PlatformView>[
156-
PlatformView(1, platformViewRect.size, PlatformViewStyling(
157-
position: PlatformViewPosition.offset(platformViewRect.topLeft)
158-
))
150+
PlatformView(1, platformViewRect, const PlatformViewStyling())
159151
]));
160152
});
161153

@@ -181,7 +173,7 @@ void testMain() {
181173
expect(slices.length, 3);
182174
expect(slices[0], pictureSliceWithRect(pictureRect1));
183175
expect(slices[1], platformViewSliceWithViews(<PlatformView>[
184-
PlatformView(1, platformViewRect.size, const PlatformViewStyling(position: PlatformViewPosition.offset(ui.Offset(150, 150))))
176+
PlatformView(1, platformViewRect, const PlatformViewStyling(position: PlatformViewPosition.offset(ui.Offset(150, 150))))
185177
]));
186178
expect(slices[2], pictureSliceWithRect(const ui.Rect.fromLTRB(200, 200, 300, 300)));
187179
});
@@ -247,8 +239,7 @@ class PlatformViewSliceMatcher extends Matcher {
247239
print('viewID mismatch');
248240
return false;
249241
}
250-
if (expectedView.size != actualView.size) {
251-
print('size mismatch');
242+
if (expectedView.bounds != actualView.bounds) {
252243
return false;
253244
}
254245
if (expectedView.styling != actualView.styling) {

lib/web_ui/test/engine/scene_view_test.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,8 @@ void testMain() {
152152

153153
final PlatformView platformView = PlatformView(
154154
1,
155-
const ui.Size(100, 120),
156-
const PlatformViewStyling(
157-
position: PlatformViewPosition.offset(ui.Offset(50, 80)),
158-
));
155+
const ui.Rect.fromLTWH(50, 80, 100, 120),
156+
const PlatformViewStyling());
159157
final EngineRootLayer rootLayer = EngineRootLayer();
160158
rootLayer.slices.add(PlatformViewSlice(<PlatformView>[platformView], null));
161159
final EngineScene scene = EngineScene(rootLayer);

lib/web_ui/test/ui/platform_view_test.dart

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,47 @@ Future<void> testMain() async {
132132
await matchGoldenFile('platformview_transformed.png', region: region);
133133
});
134134

135+
test('offset platformview', () async {
136+
await _createPlatformView(1, platformViewType);
137+
138+
final ui.PictureRecorder recorder = ui.PictureRecorder();
139+
final ui.Canvas canvas = ui.Canvas(recorder);
140+
canvas.drawCircle(
141+
const ui.Offset(50, 50),
142+
50,
143+
ui.Paint()
144+
..style = ui.PaintingStyle.fill
145+
..color = const ui.Color(0xFFFF0000)
146+
);
147+
148+
final ui.Picture picture = recorder.endRecording();
149+
150+
final ui.SceneBuilder sb = ui.SceneBuilder();
151+
sb.pushOffset(50, 50);
152+
sb.addPicture(const ui.Offset(100, 100), picture);
153+
154+
final ui.EngineLayer retainedPlatformView = sb.pushOffset(50, 50);
155+
sb.addPlatformView(
156+
1,
157+
offset: const ui.Offset(125, 125),
158+
width: 50,
159+
height: 50,
160+
);
161+
await renderScene(sb.build());
162+
163+
await matchGoldenFile('platformview_offset.png', region: region);
164+
165+
final ui.SceneBuilder sb2 = ui.SceneBuilder();
166+
sb2.pushOffset(0, 0);
167+
sb2.addPicture(const ui.Offset(100, 100), picture);
168+
169+
sb2.addRetained(retainedPlatformView);
170+
await renderScene(sb2.build());
171+
172+
await matchGoldenFile('platformview_offset_moved.png', region: region);
173+
});
174+
175+
135176
test('platformview with opacity', () async {
136177
await _createPlatformView(1, platformViewType);
137178

@@ -149,7 +190,7 @@ Future<void> testMain() async {
149190
sb.pushOffset(0, 0);
150191
sb.addPicture(const ui.Offset(100, 100), recorder.endRecording());
151192

152-
sb.pushOpacity(127);
193+
sb.pushOpacity(127, offset: const ui.Offset(50, 50));
153194
sb.addPlatformView(
154195
1,
155196
offset: const ui.Offset(125, 125),

0 commit comments

Comments
 (0)