Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GL_INCOMPATIBLE even with WebGL2 support #186

Closed
igor9silva opened this issue Aug 16, 2020 · 22 comments
Closed

GL_INCOMPATIBLE even with WebGL2 support #186

igor9silva opened this issue Aug 16, 2020 · 22 comments

Comments

@igor9silva
Copy link
Contributor

Hi,

I'm facing a problem very similar to #163 on a Samsung's Galaxy J3 (older model), a Motorola's Moto G4 Play and a Samsung's Galaxy J6+. All of them return GL_INCOMPATIBLE on callbackReady().

As per the compatibility description in the README, all of those 3 models should support Jeeliz properly. I understand the difficulties of relying on different hardware and OpenGL implementations though.

Context

We're running a proof of concept for a skin tone research, where we color-correct the image using a grey card. This lib has been extremely helpful on properly positioning the user face on the image (position, distance and angle).

Right now we're asking close people to try it out in order to gather feedback regarding UX and reliability.

What we have now

I'll focus on the Galaxy J3 which I can contact the phone owner easily.

Error happens on both Firefox 80.0.0-beta.6 (Build #2015757457) and Chrome 84.0.4147.125. It's running on Android 7.0 (kernel 3.18.14-14795764). It says Galaxy J3 Prime on the about menu (phone name) and model number SM-J327T1.

WebGL Report says that WebGL 2 (88 of 88 functions) and WebGL 1 (including FLOAT and HALF_FLOAT) are compatible. Screenshots attached at the bottom.

This demo won't run as well (blank page). I unfortunately can't access the device's console log. I can request tests on other demos as well if you find helpful.

Read Pixels Test is ok as well ("everything is fine bro"), from #41.

Our implementation

Our client code is pretty simple (single < 300 lines JS file) and relies on Jeeliz and Babel only.

Main code:

JEEFACEFILTERAPI.init({
	canvasId: CANVAS_ID,
	NNCpath: 'dist/',
	callbackReady: function(errCode, spec) {

		document.getElementById('loading').style.visibility = 'hidden';

		if (errCode) {
			console.log('Error: ', errCode);
			document.getElementById('text').innerHTML = `Failed to load câemra. Error code: ${errCode}.`;
			return;
		}

		document.getElementById('buttonWrapper').style.visibility = 'visible';
		document.getElementById(HEAD_ID).style.visibility = 'visible';

		CVD = JEEFACEFILTERAPI.Canvas2DDisplay(spec);

		docResized(); // perform an initial resize
	},

	// called at each render iteration (drawing loop):
	callbackTrack: (detectState) => {
		// * hidden for simplicity sake *
		// we only render a black rectangle on the canvas and update some DOM elements here
	},
});

Maybe not relevant, but we do call docResized on window`s resize event to fix the canvas aspect ratio. This isn't very performant but works pretty well:

const docResized = () => {

	const vWidth = window.innerWidth;
	const vHeight = window.innerHeight;
	const aspectRatio = vWidth / vHeight;
	const isAspectRatioWider = (aspectRatio > PREFERRED_ASPECT_RATIO);

	const canvas = document.getElementById(CANVAS_ID);

	const setRelativeHeigth = () => {
		setElementWidth(canvas, vWidth);
		setElementHeigth(canvas, vWidth / PREFERRED_ASPECT_RATIO);
	}

	const setRelativeWidth = () => {
		setElementHeigth(canvas, vHeight);
		setElementWidth(canvas, vHeight * PREFERRED_ASPECT_RATIO);
	}

	isAspectRatioWider ? setRelativeWidth() : setRelativeHeigth();

	const canvasRect = canvas.getBoundingClientRect();

	updateCardSize(canvasRect);
	updateHeadSize(canvasRect);

	CVD.resize();
	JEEFACEFILTERAPI.resize();
}

Screenshots

Note: many texts are in portuguese, please let me know if you need any translation.

57578d45-088e-408c-82b6-b18270db3742

image

image

image

image

image

image

image

@igor9silva
Copy link
Contributor Author

Hey @xavierjs (and other Jeeliz folks), just using this thread to thank you for the amazing work you've done here. Jeeliz libs make so many web use cases possible with a top notch quality.

I haven't found contributing instructions on your docs, but would like to help in anyway. I'm very far from being a ML or image expert, but please let me know if my or my colleague's time can be useful!

@igor9silva
Copy link
Contributor Author

I'm not sure of how do you check for WebGL 2 compatibility, but webglreport.com is apparently doing a very basic check, which leads to false-postitives. See: CesiumGS/webglreport#43.

I've done the mentioned test myself on iOS 13.6. Enabling WebGL 2 on experimental Safari features will lead webglreport.com to report as compatible (100%, 88 out of 88 functions) but oficial Khronos test fails for the majority units.

Perhaps Jeeliz is facing WebGL 2 errors and not properly fallbacking to WebGL 1 (even though iOS did handle my app and your demos properly with the flag on). What do you think?

Also, is there any easy way to force WebGL 1? I've tried, but it's very hard to tweak anything on minified code.

@igor9silva
Copy link
Contributor Author

FYI: there is one Experimental Feature called Capture video in UIProcess which seem to break Jeeliz (video input axis appear inverted).

IMG_4D4572778C85-1

@xavierjs
Copy link
Member

Hi @igor9silva

Thank you very much for this detailed bug report.
I also think it is linked to this issue: #163
Too many devices are concerned, including recent ones and I will do my best to fix it (when it was only the N5001 I thought it was some driver bug but now I think there is definitely something wrong).

Can you send me a screenshot of the bottom of the webgl2 report page (with the list of extensions): https://webglreport.com/?v=2 ?

I think it is related to this problem: https://stackoverflow.com/questions/56829454/unable-to-generate-mipmap-for-half-float-texture

I have to refactor some stuffs then I will send some links to test.

Best,
Xavier

@igor9silva
Copy link
Contributor Author

Hi @xavierjs, thanks for the quick reply! I've attached the screenshots below.

It's great to know that you already have a candidate cause! Please let me know if I can help you in anyway, just @ me.

image
image

@xavierjs
Copy link
Member

Hi,

I have changed many stuffs in the core.
Can you test again? Like the boilerplate here: https://jeeliz.com/demos/faceFilter/demos/threejs/cube/
Please open it in a private browser tab to avoid any cache problem.

Thank you very much

@xavierjs
Copy link
Member

@igor9silva Does it work mate?

@igor9silva
Copy link
Contributor Author

igor9silva commented Aug 21, 2020

Hi @xavierjs, I was just able to test. Unfortunately the results were the very same ones, at least on the J3.

I've requests new tests on the other models.

Also updated our app with the newer dist, but observed no difference.

@xavierjs
Copy link
Member

Hi @igor9silva

Thank you very much for your test.
Can you go here: https://jeeliz.com/demos/WebGLCoreLogger/index.html
and:

  • accept the camera video stream
  • click on "Copy to clipboard*. It will copy all the verbose logs from the textarea to the clipboard
  • paste it here or in a separate GIST.

Thank you very much.

@igor9silva
Copy link
Contributor Author

Hi @xavierjs,

Here is the gist for the J3: https://gist.github.com/igor9silva/50f608b72bc96c01a837000766d283ce

I also have good news, the Moto G4 Play and Galaxy J6+ owners did report success after the last update! I'm not 100% sure that this update did the trick, but the timing (their reports vs the moment I've updated with your latest build) matches perfectly.

@xavierjs
Copy link
Member

Hi @igor9silva

Great for Moto G4 Play and Galaxy J6+. I really think it is thanks to the latest update since I corrected some major bugs.
Thank you very much for this log. It seems that the J3 cannot render to float or half float texture.
It is a real problem for this library but also for many 3D algorithms that require this capability (deferred shading, zForward pass, water simulation, ...). I will look if it is a limitation on the GPU itself or the WebGL2 implementation.

@xavierjs
Copy link
Member

Hi @igor9silva

The Samsung J3 is really too weak to support this library I think.
I like this benchmark website: https://gfxbench.com/compare.jsp?benchmark=gfx40&D1=Samsung+Galaxy+J3+2017+%28SM-J330%29&os1=Android&api1=gl&hwtype1=GPU&hwname1=ARM+Mali-T720
I usually compare a device to a Samsung A5 2017 which is the lower compatible device or to Iphone6.
The J3 is really below so I am quite pessimistic about the experience even if it was compatible.

I will still add more parameters combination to find if there is a way to do render to texture on your device, and send you another link to test.

Best,
Xavier

@xavierjs
Copy link
Member

Hi @igor9silva

Can you test again (in a new private window in order to avoid any browser cache problem): https://jeeliz.com/demos/WebGLCoreLogger/index.html

Thank you very much,
Xavier

@igor9silva
Copy link
Contributor Author

igor9silva commented Aug 26, 2020

Hi,

Here is the returned:

INFO in lib_getUserMedia() - get(): constraints = {"video":{"facingMode":{"ideal":"user"},"width":{"min":480,"max":1280,"ideal":800},"height":{"min":480,"max":1280,"ideal":600}},"audio":false}
INFO in lib_getUserMedia - get_raw(): videoStream got
INFO in lib_getUserMedia - get_raw(): video.onloadedmetadata dispatched
INFO in lib_getUserMedia - get_raw(): playPromise accepted
WARNING in lib_getUserMedia - get_raw(): Image Capture API not found
INFO in lib_getUserMedia - get_raw(): callbackSuccess called with constraints=
{"facingMode":{"ideal":"user"},"width":{"min":480,"max":1280,"ideal":800},"height":{"min":480,"max":1280,"ideal":600}}
INFO in WebGLCoreLogger: VIDEO GOT! Start PlayerFF
============ INIT ContextFF ============
INFO in ContextFF: webglOptions =  {"antialias":true,"alpha":true,"preserveDrawingBuffer":true,"premultipliedAlpha":true,"stencil":false,"depth":true}
INFO in ContextFF: test if WebGL2 implementation is valid...
============ BEGIN SharedContext determine_floatRTTCapability() ============
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA32F, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA16F, glPixelType = gl.HALF_FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.HALF_FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
DEBUG: begin Samsung J3 tests
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA16F, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
END: begin Samsung J3 tests
============ END SharedContext determine_floatRTTCapability() ============
WARNING in ContextFF - is_validWebGL2(): WebGL2 is here but we cannot RTT on float or half float textures
INFO in ContextFF: isValidWebGL2 =  false
WARNING in ContextFF: Turn off antialiasing because WebGL2 sucks with it
INFO in ContextFF: test if WebGL2 implementation is valid...
============ BEGIN SharedContext determine_floatRTTCapability() ============
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA32F, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA16F, glPixelType = gl.HALF_FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.HALF_FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
DEBUG: begin Samsung J3 tests
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA16F, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
END: begin Samsung J3 tests
============ END SharedContext determine_floatRTTCapability() ============
WARNING in ContextFF - is_validWebGL2(): WebGL2 is here but we cannot RTT on float or half float textures
INFO in ContextFF: isValidWebGL2 =  false
WARNING in ContextFF - init: WebGL2 implementation is crappy. Use WebGL1
INFO in ContextFF - init: We try to create a WebGL1 context (WebGL2 is not implemented or its implementation sucks)
INFO in ContextFF - init: a WebGL1 context has been created successfully
INFO in SharedContext: enable_floatExtensions()
INFO in SharedContext: enable_halfFloatExtensions()
INFO in SharedTexture: init()
============ BEGIN SharedContext determine_floatRTTCapability() ============
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = [GL.KEYNOTFOUND for 36193]
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
DEBUG: begin Samsung J3 tests
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
END: begin Samsung J3 tests
============ END SharedContext determine_floatRTTCapability() ============
ERROR in SharedContext - determine_capabilities(): cannot do RTT on float and half float textures
ERROR in ContextFF:  Not enough GL capabilities
FATAL ERROR in WebGLCoreLogger: GL_INCOMPATIBLE

@xavierjs
Copy link
Member

Thank you. It really does not want to render to texture with float / half-float precision =(

@igor9silva
Copy link
Contributor Author

I see... thanks for all your effort @xavierjs! Let me know if you need any more tests.

@xavierjs
Copy link
Member

What's up about this issue? I pushed a couple of fixes these later months, maybe it will work.

@igor9silva
Copy link
Contributor Author

I don't have access to the device anymore, unfortunately. I'll let you know if that issue appears again. Thanks!

@AlexandreMuskus
Copy link

AlexandreMuskus commented Apr 20, 2021

Boa noite pessoal!
Estou com o mesmo problema com o J5 Prime, segue log

============ INIT ContextFF ============
INFO in ContextFF: webglOptions = {"antialias":true,"alpha":true,"preserveDrawingBuffer":true,"premultipliedAlpha":true,"stencil":false,"depth":true}
INFO in ContextFF: test if WebGL2 implementation is valid...
============ BEGIN SharedContext determine_floatRTTCapability() ============
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA32F, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA16F, glPixelType = gl.HALF_FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.HALF_FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
============ END SharedContext determine_floatRTTCapability() ============
WARNING in ContextFF - is_validWebGL2(): WebGL2 is here but we cannot RTT on float or half float textures
INFO in ContextFF: isValidWebGL2 = false
WARNING in ContextFF: Turn off antialiasing because WebGL2 sucks with it
INFO in ContextFF: test if WebGL2 implementation is valid...
============ BEGIN SharedContext determine_floatRTTCapability() ============
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA32F, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA16F, glPixelType = gl.HALF_FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.HALF_FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
============ END SharedContext determine_floatRTTCapability() ============
WARNING in ContextFF - is_validWebGL2(): WebGL2 is here but we cannot RTT on float or half float textures
INFO in ContextFF: isValidWebGL2 = false
WARNING in ContextFF - init: WebGL2 implementation is crappy. Use WebGL1
INFO in ContextFF - init: We try to create a WebGL1 context (WebGL2 is not implemented or its implementation sucks)
INFO in ContextFF - init: a WebGL1 context has been created successfully
INFO in SharedContext: enable_floatExtensions()
INFO in SharedContext: enable_halfFloatExtensions()
WARNING in SharedContext.enable_halfFloatExtensions(): OES_texture_half_float not found
WARNING in SharedContext.enable_halfFloatExtensions(): OES_texture_half_float_linear not found
INFO in SharedTexture: init()
============ BEGIN SharedContext determine_floatRTTCapability() ============
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
INFO in SharedContext.test_RTT(): test RTT with glInternalPixelFormat = gl.RGBA, glPixelType = gl.FLOAT
WARNING in SharedContext.test_RTT(): cannot do RTT. glStatus = gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT
============ END SharedContext determine_floatRTTCapability() ============
ERROR in SharedContext - determine_capabilities(): cannot do RTT on float and half float textures
ERROR in ContextFF: Not enough GL capabilities
FATAL ERROR in WebGLCoreLogger: GL_INCOMPATIBLE

image

@xavierjs
Copy link
Member

What's your config and your GPU? It seems very low.

@AlexandreMuskus
Copy link

that´s it :)

WhatsApp Image 2021-04-22 at 19 28 48
WhatsApp Image 2021-04-22 at 19 28 49

@xavierjs
Copy link
Member

Thank you for this information.
This phone is unfortunately too weak to support this library. It is a 2015 low-end mobile phone. It cannot do floating-point computations with WebGL. Even if your software is up to date (OS, browser), GPU capabilities are too limited.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants