mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[canvaskit] read pixels back in Picture.toImage (flutter/engine#40004)
[canvaskit] read pixels back in Picture.toImage
This commit is contained in:
parent
42748f8c92
commit
0893bbf690
@ -100,28 +100,7 @@ class CkPicture extends ManagedSkiaObject<SkPicture> implements ui.Picture {
|
||||
}
|
||||
|
||||
@override
|
||||
ui.Image toImageSync(int width, int height) {
|
||||
SurfaceFactory.instance.baseSurface.ensureSurface();
|
||||
if (SurfaceFactory.instance.baseSurface.usingSoftwareBackend) {
|
||||
return toImageSyncSoftware(width, height);
|
||||
}
|
||||
return toImageSyncGPU(width, height);
|
||||
}
|
||||
|
||||
ui.Image toImageSyncGPU(int width, int height) {
|
||||
assert(debugCheckNotDisposed('Cannot convert picture to image.'));
|
||||
|
||||
final CkSurface ckSurface = SurfaceFactory.instance.baseSurface
|
||||
.createRenderTargetSurface(ui.Size(width.toDouble(), height.toDouble()));
|
||||
final CkCanvas ckCanvas = ckSurface.getCanvas();
|
||||
ckCanvas.clear(const ui.Color(0x00000000));
|
||||
ckCanvas.drawPicture(this);
|
||||
final SkImage skImage = ckSurface.surface.makeImageSnapshot();
|
||||
ckSurface.dispose();
|
||||
return CkImage(skImage);
|
||||
}
|
||||
|
||||
ui.Image toImageSyncSoftware(int width, int height) {
|
||||
CkImage toImageSync(int width, int height) {
|
||||
assert(debugCheckNotDisposed('Cannot convert picture to image.'));
|
||||
|
||||
final Surface surface = SurfaceFactory.instance.pictureToImageSurface;
|
||||
|
||||
@ -828,6 +828,64 @@ void testMain() {
|
||||
await matchGoldenFile('canvaskit_empty_scene.png',
|
||||
region: const ui.Rect.fromLTRB(0, 0, 100, 100));
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/121758
|
||||
test('resources used in temporary surfaces for Image.toByteData can cross to rendering overlays', () async {
|
||||
final Rasterizer rasterizer = CanvasKitRenderer.instance.rasterizer;
|
||||
SurfaceFactory.instance.debugClear();
|
||||
|
||||
ui.platformViewRegistry.registerViewFactory(
|
||||
'test-platform-view',
|
||||
(int viewId) => createDomHTMLDivElement()..id = 'view-0',
|
||||
);
|
||||
await createPlatformView(0, 'test-platform-view');
|
||||
|
||||
CkPicture makeTextPicture(String text, ui.Offset offset) {
|
||||
final CkPictureRecorder recorder = CkPictureRecorder();
|
||||
final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
|
||||
final CkParagraphBuilder builder = CkParagraphBuilder(CkParagraphStyle());
|
||||
builder.addText(text);
|
||||
final CkParagraph paragraph = builder.build();
|
||||
paragraph.layout(const ui.ParagraphConstraints(width: 100));
|
||||
canvas.drawRect(
|
||||
ui.Rect.fromLTWH(offset.dx, offset.dy, paragraph.width, paragraph.height).inflate(10),
|
||||
CkPaint()..color = const ui.Color(0xFF00FF00)
|
||||
);
|
||||
canvas.drawParagraph(paragraph, offset);
|
||||
return recorder.endRecording();
|
||||
}
|
||||
|
||||
CkPicture imageToPicture(CkImage image, ui.Offset offset) {
|
||||
final CkPictureRecorder recorder = CkPictureRecorder();
|
||||
final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
|
||||
canvas.drawImage(image, offset, CkPaint());
|
||||
return recorder.endRecording();
|
||||
}
|
||||
|
||||
final CkPicture helloPicture = makeTextPicture('Hello', ui.Offset.zero);
|
||||
|
||||
final CkImage helloImage = helloPicture.toImageSync(100, 100);
|
||||
|
||||
// Calling toByteData is essential to hit the bug.
|
||||
await helloImage.toByteData(format: ui.ImageByteFormat.png);
|
||||
|
||||
final LayerSceneBuilder sb = LayerSceneBuilder();
|
||||
sb.pushOffset(0, 0);
|
||||
sb.addPicture(ui.Offset.zero, helloPicture);
|
||||
sb.addPlatformView(0, width: 10, height: 10);
|
||||
|
||||
// The image is rendered after the platform view so that it's rendered into
|
||||
// a separate surface, which is what triggers the bug. If the bug is present
|
||||
// the image will not appear on the UI.
|
||||
sb.addPicture(const ui.Offset(0, 50), imageToPicture(helloImage, ui.Offset.zero));
|
||||
sb.pop();
|
||||
|
||||
// The below line should not throw an error.
|
||||
rasterizer.draw(sb.build().layerTree);
|
||||
|
||||
await matchGoldenFile('cross_overlay_resources.png', region: const ui.Rect.fromLTRB(0, 0, 100, 100));
|
||||
});
|
||||
|
||||
// TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520
|
||||
}, skip: isSafari || isFirefox);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user