Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 5 additions & 36 deletions lib/web_ui/lib/src/engine/scene_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ typedef RenderResult = ({
// composite pictures into the canvases in the DOM tree it builds.
abstract class PictureRenderer {
FutureOr<RenderResult> renderPictures(List<ScenePicture> picture);
ScenePicture clipPicture(ScenePicture picture, ui.Rect clip);
}

class _SceneRender {
Expand Down Expand Up @@ -87,49 +86,20 @@ class EngineSceneView {
}
}

ScenePicture _clipPictureIfNeeded(ScenePicture picture, ui.Rect clip) {
final ui.Rect pictureRect = picture.cullRect;
if (pictureRect.left >= clip.left &&
pictureRect.top >= clip.top &&
pictureRect.right <= clip.right &&
pictureRect.bottom <= clip.bottom) {
// The picture is already within the clip bounds.
return picture;
}

return pictureRenderer.clipPicture(picture, clip);
}

ui.Rect? _getScreenBounds() {
final DomScreen? screen = domWindow.screen;
if (screen == null) {
return null;
}
return ui.Rect.fromLTWH(0, 0, screen.width, screen.height);
}

Future<void> _renderScene(EngineScene scene, FrameTimingRecorder? recorder) async {
final ui.Rect? screenBounds = _getScreenBounds();
if (screenBounds == null) {
// The browser isn't displaying the document. Skip rendering.
return;
}
final List<LayerSlice> slices = scene.rootLayer.slices;
final List<ScenePicture> picturesToRender = <ScenePicture>[];
final List<ScenePicture> originalPicturesToRender = <ScenePicture>[];
for (final LayerSlice slice in slices) {
if (slice is PictureSlice && !slice.picture.cullRect.isEmpty) {
originalPicturesToRender.add(slice.picture);
final ScenePicture clippedPicture = _clipPictureIfNeeded(slice.picture, screenBounds);
picturesToRender.add(clippedPicture);
if (slice is PictureSlice) {
picturesToRender.add(slice.picture);
}
}
final Map<ScenePicture, DomImageBitmap> renderMap;
if (picturesToRender.isNotEmpty) {
final RenderResult renderResult = await pictureRenderer.renderPictures(picturesToRender);
renderMap = <ScenePicture, DomImageBitmap>{
for (int i = 0; i < picturesToRender.length; i++)
originalPicturesToRender[i]: renderResult.imageBitmaps[i],
picturesToRender[i]: renderResult.imageBitmaps[i],
};
recorder?.recordRasterStart(renderResult.rasterStartMicros);
recorder?.recordRasterFinish(renderResult.rasterEndMicros);
Expand All @@ -155,11 +125,10 @@ class EngineSceneView {
}
}

final ui.Rect clippedBounds = slice.picture.cullRect.intersect(screenBounds);
if (container != null) {
container.bounds = clippedBounds;
container.bounds = slice.picture.cullRect;
} else {
container = PictureSliceContainer(clippedBounds);
container = PictureSliceContainer(slice.picture.cullRect);
}
container.updateContents();
container.renderBitmap(renderMap[slice.picture]!);
Expand Down
10 changes: 0 additions & 10 deletions lib/web_ui/lib/src/engine/skwasm/skwasm_impl/renderer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -482,14 +482,4 @@ class SkwasmPictureRenderer implements PictureRenderer {
@override
FutureOr<RenderResult> renderPictures(List<ScenePicture> pictures) =>
surface.renderPictures(pictures.cast<SkwasmPicture>());

@override
ScenePicture clipPicture(ScenePicture picture, ui.Rect clip) {
final ui.PictureRecorder recorder = ui.PictureRecorder();
final ui.Canvas canvas = ui.Canvas(recorder, clip);
canvas.clipRect(clip);
canvas.drawPicture(picture);

return recorder.endRecording() as ScenePicture;
}
}
24 changes: 0 additions & 24 deletions lib/web_ui/test/engine/scene_view_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,7 @@ class StubPictureRenderer implements PictureRenderer {
);
}

@override
ScenePicture clipPicture(ScenePicture picture, ui.Rect clip) {
clipRequests[picture] = clip;
return picture;
}

List<ScenePicture> renderedPictures = <ScenePicture>[];
Map<ScenePicture, ui.Rect> clipRequests = <ScenePicture, ui.Rect>{};
}

void testMain() {
Expand Down Expand Up @@ -156,21 +149,4 @@ void testMain() {
expect(stubPictureRenderer.renderedPictures.first, pictures.first);
expect(stubPictureRenderer.renderedPictures.last, pictures.last);
});

test('SceneView clips pictures that are outside the window screen', () async {
final StubPicture picture = StubPicture(const ui.Rect.fromLTWH(
-50,
-50,
100,
120,
));

final EngineRootLayer rootLayer = EngineRootLayer();
rootLayer.slices.add(PictureSlice(picture));
final EngineScene scene = EngineScene(rootLayer);
await sceneView.renderScene(scene, null);

expect(stubPictureRenderer.renderedPictures.length, 1);
expect(stubPictureRenderer.clipRequests.containsKey(picture), true);
});
}