[canvaskit] Handle MakeGrContext returning null (#163332)

Mark up the CanvasKit binding API to acknowledge that `MakeGrContext`
can return null.

Towards https://github.com/flutter/flutter/issues/162868

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Harry Terkelsen 2025-02-14 15:36:26 -08:00 committed by GitHub
parent 1a66848189
commit 92281aae46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 24 additions and 6 deletions

View File

@ -158,8 +158,8 @@ extension CanvasKitExtension on CanvasKit {
_GetOffscreenWebGLContext(canvas, options).toDartDouble;
@JS('MakeGrContext')
external SkGrContext _MakeGrContext(JSNumber glContext);
SkGrContext MakeGrContext(double glContext) => _MakeGrContext(glContext.toJS);
external SkGrContext? _MakeGrContext(JSNumber glContext);
SkGrContext? MakeGrContext(double glContext) => _MakeGrContext(glContext.toJS);
@JS('MakeOnScreenGLSurface')
external SkSurface? _MakeOnScreenGLSurface(

View File

@ -403,6 +403,8 @@ class Surface extends DisplayCanvas {
if (_glContext != 0) {
_grContext = canvasKit.MakeGrContext(glContext.toDouble());
if (_grContext == null) {
// TODO(harryterkelsen): Make this error message more descriptive by
// reporting the number of currently live Surfaces, https://github.com/flutter/flutter/issues/162868.
throw CanvasKitError(
'Failed to initialize CanvasKit. '
'CanvasKit.MakeGrContext returned null.',

View File

@ -1730,9 +1730,9 @@ void _paragraphTests() {
canvas,
SkWebGLContextOptions(antialias: 0, majorVersion: webGLVersion.toDouble()),
);
final SkGrContext grContext = canvasKit.MakeGrContext(glContext);
final SkGrContext? grContext = canvasKit.MakeGrContext(glContext);
final SkSurface? skSurface = canvasKit.MakeOnScreenGLSurface(
grContext,
grContext!,
100,
100,
SkColorSpaceSRGB,
@ -1755,8 +1755,8 @@ void _paragraphTests() {
canvas,
SkWebGLContextOptions(antialias: 0, majorVersion: webGLVersion.toDouble()),
).toInt();
final SkGrContext grContext = canvasKit.MakeGrContext(glContext.toDouble());
final SkSurface? surface = canvasKit.MakeRenderTarget(grContext, 1, 1);
final SkGrContext? grContext = canvasKit.MakeGrContext(glContext.toDouble());
final SkSurface? surface = canvasKit.MakeRenderTarget(grContext!, 1, 1);
expect(surface, isNotNull);
},

View File

@ -322,6 +322,22 @@ void testMain() {
expect(transferToImageBitmapCalls, 1);
}, skip: !Surface.offscreenCanvasSupported);
test('throws error if CanvasKit.MakeGrContext returns null', () async {
final Object originalMakeGrContext = js_util.getProperty(canvasKit, 'MakeGrContext');
js_util.setProperty(canvasKit, 'originalMakeGrContext', originalMakeGrContext);
js_util.setProperty(
canvasKit,
'MakeGrContext',
js_util.allowInterop((int glContext) {
return null;
}),
);
final Surface surface = Surface();
expect(() => surface.ensureSurface(const BitmapSize(10, 10)), throwsA(isA<CanvasKitError>()));
js_util.setProperty(canvasKit, 'MakeGrContext', originalMakeGrContext);
// Skipping on Firefox for now since Firefox headless doesn't support WebGL
}, skip: isFirefox);
test('can recover from MakeSWCanvasSurface failure', () async {
debugOverrideJsConfiguration(
<String, Object?>{'canvasKitForceCpuOnly': true}.jsify() as JsFlutterConfiguration?,