Bug 219023

Summary: Blank glReadPixels since iOS 14.2
Product: WebKit Reporter: paul
Component: WebGLAssignee: Nobody <webkit-unassigned>
Status: REOPENED ---    
Severity: Major CC: dino, kkinnunen, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari 14   
Hardware: iPhone / iPad   
OS: Other   
Bug Depends on:    
Bug Blocks: 263770    

Description paul 2020-11-17 00:42:30 PST
Reproduction steps:
- iOS 14.2
- go to https://labs.sketchfab.com/experiments/screenshots/#model/818a31e7b4194dc688dc19be9dcafdec
- click on "export screenshot" blue button on the right panel
- get a PNG file downloaded, but blank


Sketchfab is a webGL based app, here using glReadpixels webgl command to read pixel back from GPU framebuffer.

Since ios 14.2, on safari, glReadPixels return blank image where it was working before.

- iPhone 8+ iOS 14.2 - does not work
- iPhone 11, iOS 14.2 - does not work
VS
- iphone 7+, 13.6.1 works
Comment 1 Radar WebKit Bug Importer 2020-11-17 18:46:11 PST
<rdar://problem/71518366>
Comment 2 Kimmo Kinnunen 2020-12-14 01:23:58 PST
Thanks for the report, sorry it took so long to look at it.
I can repro the issue.

I can see the webgl element is depth==false, antialias==false, preserveDrawingBuffer==false.

In case it is easy for you to provide more info:
Would you have any more details on how you do glReadPixels?
1) is it reading the default Framebuffer or user-defined Framebuffer?
If it is user-defined:
2) What format is the texture attachment? Does the texture attachment have alpha?
3) Anything out-of-ordinary with the framebuffer?
Comment 3 paul 2020-12-14 03:34:40 PST
1) is it reading the default Framebuffer or user-defined Framebuffer?
It's user defined

2) What format is the texture attachment? Does the texture attachment have alpha?
yes

3) Anything out-of-ordinary with the framebuffer?
Nothing special RGBA unsigned byte buffer it is.
We go extra length to make sure the render is finished. (gl finisht etc.)

```

    var  canvasPixels = new Uint8Array(4 * width * height);
    var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    if (status !== gl.FRAMEBUFFER_COMPLETE) {
        return console.error('FRAMEBUFFER status invalid.', status);
    }
    gl.flush();
    gl.finish();
    gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, canvasPixels);
```
Comment 4 Kimmo Kinnunen 2021-01-14 06:47:44 PST
This is now fixed in trunk, but it's unclear which commit.

I tried to revert:
 - "Enable some ANGLE workarounds on iOS" (bug 220203)
 - "Snapshots of WebGL content in the tab picker don't work (black map on Google M
aps)" (bug 219946)

Neither of the above reproed the problem, though.

Marking as fixed. Please reopen if more info is needed.
Comment 5 paul 2021-02-05 04:45:55 PST
somehow fixed if canvas is transparent, not if canvas is opaque

transparent canvas => 

https://jsfiddle.net/sketchfab/ej87khya/
for just embed test on ios https://jsfiddle.net/sketchfab/ej87khya/show


opaque canvas => 

https://jsfiddle.net/sketchfab/gw3xh29f/
for just embed test on ios https://jsfiddle.net/sketchfab/gw3xh29f/show

In sketchfab js webgl code, transparent/opaque canvas path implications are just that we enable the alpha option in the canvas context creation.

So it doesn't work if we switch that option "off"
here is out context creation code, with comment on the option switch ("on" it works, "off" it breaks, same exact code for the rest of application)


in our case, complete code is doesn't work with:

```
const gl = canvas.getContext('webgl', {
            powerPreference: 'high-performance',
            antialias: false, 
            depth: false,
            stencil: false,
            alpha: off, // <= switching that off but rest exact same breaks screenshotting
            premultipliedAlpha: true,
            fullscreen: false,
            preserveDrawingBuffer: false
});
```