Allow clients to cache sample count and stencil params
Bug: https://github.com/flutter/flutter/issues/117934
Change-Id: I3e5460e4f323e1909a03bd82c5be021db0cb6b06
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/628842
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/modules/canvaskit/CHANGELOG.md b/modules/canvaskit/CHANGELOG.md
index 7ed98bc..4a1772f 100644
--- a/modules/canvaskit/CHANGELOG.md
+++ b/modules/canvaskit/CHANGELOG.md
@@ -10,6 +10,8 @@
- `Paragraph.getRectsForRange` and `Paragraph.getRectsForPlaceholders` had been returning a list
of Float32Arrays upon which a property 'direction' had been monkey-patched (this was
undocumented). They now return an object `RectWithDirection`.
+- `CanvasKit.MakeOnScreenGLSurface` allows providing a cached sample count and stencil
+ value to avoid repeated lookups on Surface creation.
## [0.37.2] - 2022-11-15
@@ -257,7 +259,7 @@
### Added
- `Font.getGlyphIntercepts()`
-
+
### Fixed
- Bug with images using certain exif metadata. (skbug.com/11968)
@@ -423,7 +425,7 @@
`CanvasKit.Shader`.
- `MakeRasterDirectSurface` for giving the user direct access to drawn pixels.
- `getLineMetrics` to Paragraph.
- - `Canvas.saveLayerPaint` as an experimental, undocumented "fast path" if one only needs to pass
+ - `Canvas.saveLayerPaint` as an experimental, undocumented "fast path" if one only needs to pass
the paint.
- Support for .woff and .woff2 fonts. Disable .woff2 for reduced code size by supplying
no_woff2 to compile.sh. (This removes the code to do brotli decompression).
diff --git a/modules/canvaskit/canvaskit_bindings.cpp b/modules/canvaskit/canvaskit_bindings.cpp
index a3fb4d8..2e1a3f4 100644
--- a/modules/canvaskit/canvaskit_bindings.cpp
+++ b/modules/canvaskit/canvaskit_bindings.cpp
@@ -187,7 +187,7 @@
}
sk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrDirectContext> dContext, int width, int height,
- sk_sp<SkColorSpace> colorSpace) {
+ sk_sp<SkColorSpace> colorSpace, int sampleCnt, int stencil) {
// WebGL should already be clearing the color and stencil buffers, but do it again here to
// ensure Skia receives them in the expected state.
emscripten_glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -200,12 +200,6 @@
GrGLFramebufferInfo info;
info.fFBOID = 0;
- GrGLint sampleCnt;
- emscripten_glGetIntegerv(GL_SAMPLES, &sampleCnt);
-
- GrGLint stencil;
- emscripten_glGetIntegerv(GL_STENCIL_BITS, &stencil);
-
if (!colorSpace) {
colorSpace = SkColorSpace::MakeSRGB();
}
@@ -218,6 +212,17 @@
return surface;
}
+sk_sp<SkSurface> MakeOnScreenGLSurface(sk_sp<GrDirectContext> dContext, int width, int height,
+ sk_sp<SkColorSpace> colorSpace) {
+ GrGLint sampleCnt;
+ emscripten_glGetIntegerv(GL_SAMPLES, &sampleCnt);
+
+ GrGLint stencil;
+ emscripten_glGetIntegerv(GL_STENCIL_BITS, &stencil);
+
+ return MakeOnScreenGLSurface(dContext, width, height, colorSpace, sampleCnt, stencil);
+}
+
sk_sp<SkSurface> MakeRenderTarget(sk_sp<GrDirectContext> dContext, int width, int height) {
SkImageInfo info = SkImageInfo::MakeN32(
width, height, SkAlphaType::kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
@@ -919,7 +924,8 @@
#ifdef CK_ENABLE_WEBGL
constant("webgl", true);
- function("_MakeOnScreenGLSurface", &MakeOnScreenGLSurface);
+ function("_MakeOnScreenGLSurface", select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, int, int, sk_sp<SkColorSpace>)>(&MakeOnScreenGLSurface));
+ function("_MakeOnScreenGLSurface", select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, int, int, sk_sp<SkColorSpace>, int, int)>(&MakeOnScreenGLSurface));
function("_MakeRenderTargetWH", select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, int, int)>(&MakeRenderTarget));
function("_MakeRenderTargetII", select_overload<sk_sp<SkSurface>(sk_sp<GrDirectContext>, SimpleImageInfo)>(&MakeRenderTarget));
#endif // CK_ENABLE_WEBGL
diff --git a/modules/canvaskit/npm_build/types/canvaskit-wasm-tests.ts b/modules/canvaskit/npm_build/types/canvaskit-wasm-tests.ts
index c97f67a..374a52b 100644
--- a/modules/canvaskit/npm_build/types/canvaskit-wasm-tests.ts
+++ b/modules/canvaskit/npm_build/types/canvaskit-wasm-tests.ts
@@ -952,6 +952,11 @@
const surfaceNine = CK.MakeOnScreenGLSurface(grCtx!, 100, 400, // $ExpectType Surface
CK.ColorSpace.ADOBE_RGB)!;
+ var sample = gl.getParameter(gl.SAMPLES);
+ var stencil = gl.getParameter(gl.STENCIL_BITS);
+ const surfaceTen = CK.MakeOnScreenGLSurface(grCtx!, 100, 400, // $ExpectType Surface
+ CK.ColorSpace.ADOBE_RGB, sample, stencil)!;
+
const rt = CK.MakeRenderTarget(grCtx!, 100, 200); // $ExpectType Surface | null
const rt2 = CK.MakeRenderTarget(grCtx!, { // $ExpectType Surface | null
width: 79,
diff --git a/modules/canvaskit/npm_build/types/index.d.ts b/modules/canvaskit/npm_build/types/index.d.ts
index 3872f78..29149c7 100644
--- a/modules/canvaskit/npm_build/types/index.d.ts
+++ b/modules/canvaskit/npm_build/types/index.d.ts
@@ -256,9 +256,13 @@
* @param width - number of pixels of the width of the visible area.
* @param height - number of pixels of the height of the visible area.
* @param colorSpace
+ * @param sampleCount - sample count value from GL_SAMPLES. If not provided this will be looked up from
+ * the canvas.
+ * @param stencil - stencil count value from GL_STENCIL_BITS. If not provided this will be looked up
+ * from the WebGL Context.
*/
MakeOnScreenGLSurface(ctx: GrDirectContext, width: number, height: number,
- colorSpace: ColorSpace): Surface | null;
+ colorSpace: ColorSpace, sampleCount?: number, stencil?: number): Surface | null;
/**
* Creates a context that operates over the given WebGPU Device.
diff --git a/modules/canvaskit/tests/core_test.js b/modules/canvaskit/tests/core_test.js
index 1d6ab29..b60d152 100644
--- a/modules/canvaskit/tests/core_test.js
+++ b/modules/canvaskit/tests/core_test.js
@@ -2001,4 +2001,22 @@
grContext.delete();
expect(grContext.isDeleted()).toBeTrue();
});
+
+ it('can provide sample count and stencil parameters to onscreen surface', () => {
+ if (!CanvasKit.webgl) {
+ return SHOULD_SKIP;
+ }
+ const paramCanvas = document.createElement('canvas');
+ const gl = paramCanvas.getContext('webgl');
+ var sample = gl.getParameter(gl.SAMPLES);
+ var stencil = gl.getParameter(gl.STENCIL_BITS);
+
+ const newCanvas = document.createElement('canvas');
+ const ctx = CanvasKit.GetWebGLContext(newCanvas);
+ const grContext = CanvasKit.MakeWebGLContext(ctx);
+ expect(grContext).toBeTruthy();
+
+ var surface = CanvasKit.MakeOnScreenGLSurface(grContext, 100, 100, CanvasKit.ColorSpace.SRGB, sample, stencil);
+ expect(surface).toBeTruthy();
+ });
});
diff --git a/modules/canvaskit/webgl.js b/modules/canvaskit/webgl.js
index 47a8f90..4685f2a 100644
--- a/modules/canvaskit/webgl.js
+++ b/modules/canvaskit/webgl.js
@@ -112,11 +112,17 @@
this._setResourceCacheLimitBytes(maxResourceBytes);
};
- CanvasKit.MakeOnScreenGLSurface = function(grCtx, w, h, colorspace) {
+ CanvasKit.MakeOnScreenGLSurface = function(grCtx, w, h, colorspace, sc, st) {
if (!this.setCurrentContext(grCtx._context)) {
return null;
}
- var surface = this._MakeOnScreenGLSurface(grCtx, w, h, colorspace);
+ var surface;
+ // zero is a valid value for sample count or stencil bits.
+ if (sc === undefined || st === undefined) {
+ surface = this._MakeOnScreenGLSurface(grCtx, w, h, colorspace);
+ } else {
+ surface = this._MakeOnScreenGLSurface(grCtx, w, h, colorspace, sc, st);
+ }
if (!surface) {
return null;
}