diff --git a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart index 28bcd04e85294..840b75df57dab 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart @@ -117,6 +117,8 @@ extension CanvasKitExtension on CanvasKit { int width, int height, ColorSpace colorSpace, + int sampleCount, + int stencil, ); external SkSurface MakeSWCanvasSurface(DomCanvasElement canvas); diff --git a/lib/web_ui/lib/src/engine/canvaskit/surface.dart b/lib/web_ui/lib/src/engine/canvaskit/surface.dart index cd9b910ee694b..5fcabace0f7b6 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/surface.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/surface.dart @@ -98,6 +98,8 @@ class Surface { DomCanvasElement? htmlCanvas; int _pixelWidth = -1; int _pixelHeight = -1; + int _sampleCount = -1; + int _stencilBits = -1; /// Specify the GPU resource cache limits. void setSkiaResourceCacheMaxBytes(int bytes) { @@ -334,6 +336,9 @@ class Surface { majorVersion: webGLVersion.toDouble(), ), ).toInt(); + if (_sampleCount == -1 || _stencilBits == -1) { + _initWebglParams(); + } _glContext = glContext; @@ -352,6 +357,12 @@ class Surface { htmlElement.append(htmlCanvas); } + void _initWebglParams() { + final WebGLContext gl = htmlCanvas!.getGlContext(webGLVersion); + _sampleCount = gl.getParameter(gl.samples); + _stencilBits = gl.getParameter(gl.stencilBits); + } + CkSurface _createNewSurface(ui.Size size) { assert(htmlCanvas != null); if (webGLVersion == -1) { @@ -369,6 +380,8 @@ class Surface { size.width.ceil(), size.height.ceil(), SkColorSpaceSRGB, + _sampleCount, + _stencilBits ); if (skSurface == null) { diff --git a/lib/web_ui/lib/src/engine/dom.dart b/lib/web_ui/lib/src/engine/dom.dart index 8ee402645554b..4e18599a55e0e 100644 --- a/lib/web_ui/lib/src/engine/dom.dart +++ b/lib/web_ui/lib/src/engine/dom.dart @@ -624,6 +624,27 @@ extension DomCanvasElementExtension on DomCanvasElement { DomCanvasRenderingContext2D get context2D => getContext('2d')! as DomCanvasRenderingContext2D; + + WebGLContext getGlContext(int majorVersion) { + if (majorVersion == 1) { + return getContext('webgl')! as WebGLContext; + } + return getContext('webgl2')! as WebGLContext; + } +} + +@JS() +@staticInterop +class WebGLContext {} + +extension WebGLContextExtension on WebGLContext { + external int getParameter(int value); + + @JS('SAMPLES') + external int get samples; + + @JS('STENCIL_BITS') + external int get stencilBits; } @JS() diff --git a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart index 2eedcc1d6891f..110503ace07c3 100644 --- a/lib/web_ui/test/canvaskit/canvaskit_api_test.dart +++ b/lib/web_ui/test/canvaskit/canvaskit_api_test.dart @@ -1781,4 +1781,33 @@ void _paragraphTests() { canvasKit.TextHeightBehavior.DisableAll, ); }); + + test('MakeOnScreenGLSurface test', () { + final DomCanvasElement canvas = createDomCanvasElement( + width: 100, + height: 100, + ); + final WebGLContext gl = canvas.getGlContext(webGLVersion); + final int sampleCount = gl.getParameter(gl.samples); + final int stencilBits = gl.getParameter(gl.stencilBits); + + final int glContext = canvasKit.GetWebGLContext( + canvas, + SkWebGLContextOptions( + antialias: 0, + majorVersion: webGLVersion.toDouble(), + ), + ).toInt(); + final SkGrContext grContext = canvasKit.MakeGrContext(glContext); + final SkSurface? skSurface = canvasKit.MakeOnScreenGLSurface( + grContext, + 100, + 100, + SkColorSpaceSRGB, + sampleCount, + stencilBits + ); + + expect(skSurface, isNotNull); + }, skip: isFirefox); // Intended: Headless firefox has no webgl support https://github.com/flutter/flutter/issues/109265 }