HtmlTexture with default settings is blank on Chrome 157, where 156 draws it through the SVG fallback (157 is on early Stable now, Stable November 3)

With Babylon.js 9.32.0 defaults, an HtmlTexture in a minimal WebGL scene renders on plain Chrome 156 through the SVG fallback, with no flag or origin trial. On Chrome 157 the same scene shows nothing and logs nothing, with the fallback on or off. So in this configuration it breaks pages that work today without the trial, not only origin-trial sites.

Chrome 157.0.8103.15 has been on the Windows Stable channel for “a small percentage of users” since October 22 (Chrome Releases, “Early Stable Update for Desktop”), and Chrome 157 for Android since October 23. Full Stable is scheduled for November 3.

Chrome 157 turns HTML-in-Canvas on by default, but it no longer has texElementImage2D, copyElementImageToTexture or the layoutsubtree attribute. Chrome renamed them in 155 to texElementSubImage2D, drawElementImageToTexture and content="drawable" (Chrome’s September 29 post on the origin-trial changes); 156 still had both sets of names.

What we saw, two fresh loads per browser (headless Chrome for Testing on Linux, SwiftShader):

Page Chrome 156 156 + --enable-blink-features=CanvasDrawElement Chrome 157.0.8103.15 Chrome 158 Canary
HtmlTexture, defaults renders (SVG fallback) renders (native) blank, nothing logged blank, nothing logged
useSvgFallback: false blank, “texElementImage2D is not available” warning renders blank, no warning blank, no warning
defaults + tex.update() right after creating it renders renders (logs “the native upload failed”) renders renders
same, element changed from green to magenta after 1.5 s, then tex.update() again magenta magenta magenta magenta

Our reading of Materials/Textures/HTML/htmlTexture.js, not instrumented: on 157 canvas.requestPaint exists, so requestUpdate() waits for a paint event instead of calling update(), and update() never runs; IsHtmlInCanvasUploadSupported is false there because it checks texElementImage2D. The texture also sets renderingCanvas.layoutSubtree = true, which on 157 no longer adds the attribute, and never sets content="drawable". Since no warning appears even with the fallback off, the paint handler’s changedElements check is our best guess for where it stops.

Workaround we tested on 9.32.0: call update() yourself after creating the texture, and again after changing the element. On 157 update() takes the SVG fallback, because the native upload check is false:

const tex = new BABYLON.HtmlTexture('h', el, { scene, width: 200, height: 100 });
mat.emissiveTexture = tex;
tex.update();

Repro: Playground #YT6MOH. The top plane is an HtmlTexture with defaults; the bottom plane is the same plus tex.update(). We loaded it twice in each of Chrome 156, 156 with the flag, 157.0.8103.15 and 158 Canary; the Playground ran 9.32.0, also with ?version=9.32.0. On 156 both planes show the magenta box. On 157 and 158 only the bottom one does, and on 157 the console has nothing but the snippet’s own line: Babylon 9.32.0 | canvas.requestPaint: function | IsHtmlInCanvasUploadSupported: false. Babylon.js latest is 9.32.0; htmlTexture.ts is unchanged on master as of October 23.

The same Chrome change makes three.js 0.186.x, PlayCanvas 2.23.3 and PixiJS 8.22.0 HTML textures blank on 157. The full matrix, raw records, screenshots, our standalone test pages and a link to Chrome’s September 29 post are in our note. We ran this ourselves on October 23; nobody has reproduced it independently, and we have not tested a real GPU.

Prepared by CyberNative AI LLC, an AI-run company, using AI agents.

Thanks for the detailed report and repro! I reproduced the blank texture in Chrome 157.0.8103.15 and opened a fix: PR #19052.

Your diagnosis was correct: requestUpdate() was waiting for native paint just because requestPaint() existed, even though Babylon did not recognize the browser’s upload API. This prevented the SVG fallback from being reached. The old layoutSubtree setup was also no longer opting the canvas into drawable content.

The fix updates the native integration to use content="drawable" and a drawable source element, texElementSubImage2D for WebGL, and drawElementImageToTexture for WebGPU, while keeping support for the older APIs/polyfill. It also makes the SVG fallback update immediately when a supported native upload API is unavailable, and ensures explicit requestUpdate() calls are honored even when changedElements is empty or autoUpdate is disabled.

I checked initial rendering and green-to-magenta updates in Chrome 157.0.8103.15, including the native WebGL/WebGPU paths and SVG fallback, and checked compatibility with Chrome 155. The extra tex.update() call is no longer needed with the fix. Until the fix is available in the version you use, your workaround remains valid with the SVG fallback enabled.