Trouble with ios textures

Hi. When I trying to make screenshot on ios and add it texture to ui, sometimes it’s not load and show just black texture. but when I download screen, it’s look ok.

Hi @pekarnik,

This sounds more like a race condition, since it doesn’t happen always. Are you able to share a project to take a look?

In few hours I will make non commercial project with that and show it.
Thanks for reply

2 Likes

Sorry for long reply.
I solved this problem. On ios before add texture to the ui, I add some delay

var previewTexture = new pc.Texture(app.graphicsDevice, {
                    format: pc.PIXELFORMAT_R5_G6_B5,
                    // format: PIXELFORMAT_R8_G8_B8_A8,
                    autoMipmap: false
                });
                previewTexture.minFilter = pc.FILTER_LINEAR;
                previewTexture.magFilter = pc.FILTER_LINEAR;
                previewTexture.addressU = pc.ADDRESS_CLAMP_TO_EDGE;
                previewTexture.addressV = pc.ADDRESS_CLAMP_TO_EDGE;

                // Create HTML preview Element to play the preview
                //var preview = document.createElement('img');
                previewTexture.setSource(this.preview);
                this.preview.src = this.image.data;
                this.preview.crossOrigin = 'anonymous';
                previewTexture.upload();
                window.tools.delay(0.2, ()=>{ 
                    this.previewImage.element.texture = previewTexture;
                },this);

instead of

var previewTexture = new pc.Texture(app.graphicsDevice, {
                    format: pc.PIXELFORMAT_R5_G6_B5,
                    // format: PIXELFORMAT_R8_G8_B8_A8,
                    autoMipmap: false
                });
                previewTexture.minFilter = pc.FILTER_LINEAR;
                previewTexture.magFilter = pc.FILTER_LINEAR;
                previewTexture.addressU = pc.ADDRESS_CLAMP_TO_EDGE;
                previewTexture.addressV = pc.ADDRESS_CLAMP_TO_EDGE;

                // Create HTML preview Element to play the preview
                //var preview = document.createElement('img');
                previewTexture.setSource(this.preview);
                this.preview.src = this.image.data;
                this.preview.crossOrigin = 'anonymous';
                previewTexture.upload();
                this.previewImage.element.texture = previewTexture;

On android it’s was OK.

2 Likes

Where’s this coming from? An external source?

Yeap. It’s 8thwall method for screenshots.

Screenshot.prototype.postRender = function () {
    if (this._triggerScreenshot) {
        this._triggerScreenshot = false;
        XR8.CanvasScreenshot.takeScreenshot().then(
            function(data) {
                this.app.fire(this.eventAfter);
                this.previewImage.element.texture = null;
                this.image.file = "";
                var date = new Date();
                this.image.file += date.getHours() + "_" + date.getMinutes() + "_" + date.getDate() + "_" + (date.getMonth() + 1) + "_" + date.getFullYear() + ".jpg";
                this.image.data = "data:image/jpeg;base64," + data;
                
                var app = this.app;
                var previewTexture = new pc.Texture(app.graphicsDevice, {
                    format: pc.PIXELFORMAT_R5_G6_B5,
                    // format: PIXELFORMAT_R8_G8_B8_A8,
                    autoMipmap: false
                });
                previewTexture.minFilter = pc.FILTER_LINEAR;
                previewTexture.magFilter = pc.FILTER_LINEAR;
                previewTexture.addressU = pc.ADDRESS_CLAMP_TO_EDGE;
                previewTexture.addressV = pc.ADDRESS_CLAMP_TO_EDGE;

                // Create HTML preview Element to play the preview
                //var preview = document.createElement('img');
                previewTexture.setSource(this.preview);
                this.preview.src = this.image.data;
                this.preview.crossOrigin = 'anonymous';
                previewTexture.upload();
                window.tools.delay(0.2, ()=>{ 
                    this.previewImage.element.texture = previewTexture;
                },this);
                
            }.bind(this),
            function(error) {
                console.log("[screenshot]", error);
                this.app.fire(this.eventAfter);
            }.bind(this));
    }
};

I wonder if it just needs a frame to upload before assignment. Have you tried setTimeout with no time parameter to call the assignment code in the next frame?

Without parameter it’s still have a problem, with 1 ms too, but start from 2 ms it’s ok.

And it’s not always a black screen on ios without a delay, every first screenshot is ok in most of cases, but second-third have a problem, and most of next too.

1 Like