Unverified Commit b001671f authored by Dan Field's avatar Dan Field Committed by GitHub

dispose the ShaderWarmUp picture/image (#85465)

parent 540ff244
......@@ -4,7 +4,7 @@
import 'dart:io';
import 'dart:ui' show Size, hashValues;
import 'dart:ui' show Size, hashValues, Picture, Image;
import 'package:flutter/foundation.dart';
......@@ -195,3 +195,29 @@ bool debugAssertAllPaintingVarsUnset(String reason, { bool debugDisableShadowsOv
}());
return true;
}
/// The signature of [debugCaptureShaderWarmUpPicture].
///
/// Used by tests to run assertions on the [Picture] created by
/// [ShaderWarmUp.execute]. The return value indicates whether the assertions
/// pass or not.
typedef ShaderWarmUpPictureCallback = bool Function(Picture);
/// The signature of [debugCaptureShaderWarmUpImage].
///
/// Used by tests to run assertions on the [Image] created by
/// [ShaderWarmUp.execute]. The return value indicates whether the assertions
/// pass or not.
typedef ShaderWarmUpImageCallback = bool Function(Image);
/// Called by [ShaderWarmUp.execute] immediately after it creates a [Picture].
///
/// Tests may use this to capture the picture and run assertions on it.
ShaderWarmUpPictureCallback debugCaptureShaderWarmUpPicture = _defaultPictureCapture;
bool _defaultPictureCapture(Picture picture) => true;
/// Called by [ShaderWarmUp.execute] immediately after it creates an [Image].
///
/// Tests may use this to capture the picture and run assertions on it.
ShaderWarmUpImageCallback debugCaptureShaderWarmUpImage = _defaultImageCapture;
bool _defaultImageCapture(Image image) => true;
......@@ -7,6 +7,8 @@ import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'debug.dart';
/// Interface for drawing an image to warm up Skia shader compilations.
///
/// When Skia first sees a certain type of draw operation on the GPU, it needs
......@@ -85,15 +87,19 @@ abstract class ShaderWarmUp {
final ui.Canvas canvas = ui.Canvas(recorder);
await warmUpOnCanvas(canvas);
final ui.Picture picture = recorder.endRecording();
assert(debugCaptureShaderWarmUpPicture(picture));
if (!kIsWeb) { // Picture.toImage is not yet implemented on the web.
final TimelineTask shaderWarmUpTask = TimelineTask();
shaderWarmUpTask.start('Warm-up shader');
try {
await picture.toImage(size.width.ceil(), size.height.ceil());
final ui.Image image = await picture.toImage(size.width.ceil(), size.height.ceil());
assert(debugCaptureShaderWarmUpImage(image));
image.dispose();
} finally {
shaderWarmUpTask.finish();
}
}
picture.dispose();
}
}
......
......@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';
......@@ -32,4 +35,27 @@ void main() {
expect(hasDrawRectAfterClipRRect, true);
});
test('ShaderWarmUp.execute disposes the image and picture', () async {
const DefaultShaderWarmUp shaderWarmUp = DefaultShaderWarmUp();
late ui.Picture capturedPicture;
late ui.Image capturedImage;
debugCaptureShaderWarmUpPicture = (ui.Picture picture) {
capturedPicture = picture;
expect(picture.approximateBytesUsed, greaterThan(0));
return true;
};
debugCaptureShaderWarmUpImage = (ui.Image image) {
capturedImage = image;
expect(image.width, 100);
expect(image.height, 100);
return true;
};
await shaderWarmUp.execute();
expect(
() => capturedPicture.approximateBytesUsed,
throwsA(isA<String>().having((String message) => message, 'message', 'Object has been disposed.')),
);
expect(capturedImage.debugDisposed, true);
}, skip: kIsWeb); // Browser doesn't support approximateBytesUsed and doesn't rasterize the picture at this time.
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment