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

EGL X11 support #3

Open
3 of 9 tasks
tareksander opened this issue May 24, 2023 · 61 comments
Open
3 of 9 tasks

EGL X11 support #3

tareksander opened this issue May 24, 2023 · 61 comments

Comments

@tareksander
Copy link
Owner

tareksander commented May 24, 2023

  • shared memory Pixmap as a fallback option
    • Image flipping and color conversion on the CPU
    • Image flipping and color conversion in shaders, via a separate shader render (to not mess with applications calling readPixels or trying to copy from FB into a texture).
  • putImage as a fallback fallback for when using TCP sockets? Low priority, on getDisplay missing shared pixmaps are recognized and the display fails, falling back to Mesa. When you have to transmit frames over the network, CPU rendering shouldn't be the issue anyways, so it's fine.
  • extracting the DMABUF fd from a HardwareBuffer and use that for shared memory
    • Currently low performance, not known why.
    • Try the format matching the X11 format, else fall back to CPU or GPU post-processing
  • double buffering
  • implement eglSwapInterval for 0 and 1
@twaik
Copy link
Contributor

twaik commented May 24, 2023

I think it should be double buffering to not wait until X server finishes working with current buffer. But I am not sure how to implement synchronisation that will say that buffer is processed and you can really swap it. Btw Android uses triple buffering.

@tareksander
Copy link
Owner Author

X11 also has a sync protocol, and the present protocol has support for it, but it's just a bit more work to actually implement that.

@twaik
Copy link
Contributor

twaik commented May 26, 2023

Currently everything seems to be better, but still has performance close to llvmpipe.

GFX wrapper
~/gfx/build $ __EGL_VENDOR_LIBRARY_FILENAMES=/data/data/com.termux/files/usr/share/glvnd/egl_vendor.d/10_android_wrapper.json glmark2-es2 --fullscreen | grep -v -e "swap interval" -e "swap_control"
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      Imagination Technologies
    GL_RENDERER:    PowerVR Rogue GE8320
    GL_VERSION:     OpenGL ES 3.2 build 1.13@5776728
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   496x1100 fullscreen
=======================================================
Using memfd
draw resize
[build] use-vbo=false: FPS: 19 FrameTime: 54.352 ms
[build] use-vbo=true: FPS: 19 FrameTime: 53.849 ms
[texture] texture-filter=nearest: FPS: 20 FrameTime: 52.040 ms
[texture] texture-filter=linear: FPS: 20 FrameTime: 52.123 ms
[texture] texture-filter=mipmap: FPS: 20 FrameTime: 52.494 ms
[shading] shading=gouraud: FPS: 19 FrameTime: 53.474 ms
[shading] shading=blinn-phong-inf: FPS: 19 FrameTime: 54.638 ms
[shading] shading=phong: FPS: 18 FrameTime: 58.345 ms
[shading] shading=cel: FPS: 18 FrameTime: 57.301 ms
[bump] bump-render=high-poly: FPS: 16 FrameTime: 64.503 ms
[bump] bump-render=normals: FPS: 19 FrameTime: 53.655 ms
[bump] bump-render=height: FPS: 19 FrameTime: 52.851 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 19 FrameTime: 55.149 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 16 FrameTime: 66.485 ms
[pulsar] light=false:quads=5:texture=false: FPS: 20 FrameTime: 52.374 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 20 FrameTime: 51.078 ms
[desktop] effect=shadow:windows=4: FPS: 20 FrameTime: 52.312 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 20 FrameTime: 52.131 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 19 FrameTime: 53.551 ms
[jellyfish] <default>: FPS: 16 FrameTime: 66.005 ms
[terrain] <default>: FPS: 15 FrameTime: 67.724 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 20 FrameTime: 52.124 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 18 FrameTime: 56.074 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 19 FrameTime: 53.354 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 19 FrameTime: 53.069 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 18 FrameTime: 58.310 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 19 FrameTime: 52.844 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 19 FrameTime: 53.887 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 19 FrameTime: 54.846 ms
=======================================================
                                  glmark2 Score: 17 
=======================================================
llvmpipe
~/gfx/build $ __EGL_VENDOR_LIBRARY_FILENAMES=/data/data/com.termux/files/usr/share/glvnd/egl_vendor.d/50_mesa.json glmark2-es2 --fullscreen | grep -v -e "swap interval" -e "swap_control"
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      Mesa
    GL_RENDERER:    llvmpipe (LLVM 16.0.2, 128 bits)
    GL_VERSION:     OpenGL ES 3.2 Mesa 23.0.3
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=32 stencil=0 samples=0
    Surface Size:   496x1100 fullscreen
=======================================================
[build] use-vbo=false: FPS: 20 FrameTime: 51.601 ms
[build] use-vbo=true: FPS: 20 FrameTime: 51.321 ms
[texture] texture-filter=nearest: FPS: 24 FrameTime: 43.439 ms
[texture] texture-filter=linear: FPS: 21 FrameTime: 48.331 ms
[texture] texture-filter=mipmap: FPS: 19 FrameTime: 54.705 ms
[shading] shading=gouraud: FPS: 16 FrameTime: 64.575 ms
[shading] shading=blinn-phong-inf: FPS: 14 FrameTime: 71.614 ms
[shading] shading=phong: FPS: 13 FrameTime: 82.456 ms
[shading] shading=cel: FPS: 13 FrameTime: 82.226 ms
[bump] bump-render=high-poly: FPS: 8 FrameTime: 140.636 ms
[bump] bump-render=normals: FPS: 22 FrameTime: 47.355 ms
[bump] bump-render=height: FPS: 22 FrameTime: 47.229 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 16 FrameTime: 63.544 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 13 FrameTime: 79.889 ms
[pulsar] light=false:quads=5:texture=false: FPS: 18 FrameTime: 57.728 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 7 FrameTime: 143.864 ms
[desktop] effect=shadow:windows=4: FPS: 10 FrameTime: 100.122 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 15 FrameTime: 66.745 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 16 FrameTime: 66.212 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 16 FrameTime: 62.757 ms
[ideas] speed=duration: FPS: 16 FrameTime: 66.087 ms
[jellyfish] <default>: FPS: 6 FrameTime: 186.015 ms
[terrain] <default>: FPS: 1 FrameTime: 1232.327 ms
[shadow] <default>: FPS: 9 FrameTime: 113.531 ms
[refract] <default>: FPS: 2 FrameTime: 874.884 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 18 FrameTime: 56.394 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 17 FrameTime: 59.844 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 18 FrameTime: 56.564 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 17 FrameTime: 60.086 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 16 FrameTime: 65.105 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 17 FrameTime: 59.618 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 17 FrameTime: 59.758 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 16 FrameTime: 65.176 ms
=======================================================
                                  glmark2 Score: 13 
=======================================================

@twaik
Copy link
Contributor

twaik commented May 26, 2023

And glmark2 working on llvmpipe + virpipe working on the same device.

llvmpipe
~/gfx/build $ glmark2 --fullscreen
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      Mesa
    GL_RENDERER:    llvmpipe (LLVM 16.0.2, 128 bits)
    GL_VERSION:     4.5 (Compatibility Profile) Mesa 23.0.3
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=32 stencil=0 samples=0
    Surface Size:   496x1100 fullscreen
=======================================================
[build] use-vbo=false: FPS: 23 FrameTime: 44.918 ms
[build] use-vbo=true: FPS: 23 FrameTime: 44.639 ms
[texture] texture-filter=nearest: FPS: 28 FrameTime: 36.560 ms
[texture] texture-filter=linear: FPS: 25 FrameTime: 40.725 ms
[texture] texture-filter=mipmap: FPS: 22 FrameTime: 46.748 ms
[shading] shading=gouraud: FPS: 18 FrameTime: 57.262 ms
[shading] shading=blinn-phong-inf: FPS: 16 FrameTime: 64.630 ms
[shading] shading=phong: FPS: 14 FrameTime: 73.782 ms
[shading] shading=cel: FPS: 14 FrameTime: 73.575 ms
[bump] bump-render=high-poly: FPS: 8 FrameTime: 133.061 ms
[bump] bump-render=normals: FPS: 26 FrameTime: 39.431 ms
[bump] bump-render=height: FPS: 26 FrameTime: 39.147 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 19 FrameTime: 53.665 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 15 FrameTime: 69.461 ms
[pulsar] light=false:quads=5:texture=false: FPS: 22 FrameTime: 46.765 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 8 FrameTime: 135.397 ms
[desktop] effect=shadow:windows=4: FPS: 12 FrameTime: 86.790 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 17 FrameTime: 59.567 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 17 FrameTime: 59.294 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 18 FrameTime: 55.738 ms
[ideas] speed=duration: FPS: 18 FrameTime: 57.948 ms
[jellyfish] <default>: FPS: 6 FrameTime: 175.856 ms
[terrain] <default>: FPS: 1 FrameTime: 1071.449 ms
[shadow] <default>: FPS: 10 FrameTime: 105.026 ms
[refract] <default>: FPS: 2 FrameTime: 875.674 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 21 FrameTime: 49.333 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 19 FrameTime: 53.047 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 21 FrameTime: 49.431 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 20 FrameTime: 52.443 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 18 FrameTime: 58.145 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 20 FrameTime: 52.388 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 20 FrameTime: 52.452 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 18 FrameTime: 58.096 ms
=======================================================
                                  glmark2 Score: 16 
=======================================================
virpipe
~/gfx/build $ GALLIUM_DRIVER=virpipe glmark2 --fullscreen
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      Mesa
    GL_RENDERER:    virgl (PowerVR Rogue GE8320)
    GL_VERSION:     2.1 Mesa 23.0.3
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=32 stencil=0 samples=0
    Surface Size:   496x1100 fullscreen
=======================================================
[build] use-vbo=false: FPS: 44 FrameTime: 23.143 ms
[build] use-vbo=true: FPS: 46 FrameTime: 21.743 ms
[texture] texture-filter=nearest: FPS: 47 FrameTime: 21.342 ms
[texture] texture-filter=linear: FPS: 48 FrameTime: 21.091 ms
[texture] texture-filter=mipmap: FPS: 48 FrameTime: 21.205 ms
[shading] shading=gouraud: FPS: 45 FrameTime: 22.490 ms
[shading] shading=blinn-phong-inf: FPS: 44 FrameTime: 22.769 ms
[shading] shading=phong: FPS: 42 FrameTime: 23.976 ms
[shading] shading=cel: FPS: 41 FrameTime: 24.531 ms
[bump] bump-render=high-poly: FPS: 39 FrameTime: 25.829 ms
[bump] bump-render=normals: FPS: 46 FrameTime: 22.190 ms
[bump] bump-render=height: FPS: 45 FrameTime: 22.557 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 44 FrameTime: 22.929 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 38 FrameTime: 26.827 ms
[pulsar] light=false:quads=5:texture=false: FPS: 46 FrameTime: 21.991 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 33 FrameTime: 30.670 ms
[desktop] effect=shadow:windows=4: FPS: 40 FrameTime: 25.132 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 32 FrameTime: 31.447 ms
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 22 FrameTime: 46.453 ms
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 37 FrameTime: 27.214 ms
[ideas] speed=duration: FPS: 36 FrameTime: 27.800 ms
[jellyfish] <default>: FPS: 36 FrameTime: 28.257 ms
[terrain] <default>: FPS: 15 FrameTime: 68.117 ms
[shadow] <default>: FPS: 37 FrameTime: 27.763 ms
[refract] <default>: FPS: 18 FrameTime: 57.925 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 46 FrameTime: 22.026 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 44 FrameTime: 22.941 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 46 FrameTime: 22.139 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 45 FrameTime: 22.525 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 42 FrameTime: 24.372 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 45 FrameTime: 22.467 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 44 FrameTime: 22.989 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 44 FrameTime: 23.122 ms
=======================================================
                                  glmark2 Score: 39 
=======================================================

@twaik
Copy link
Contributor

twaik commented May 26, 2023

Interesting thing, without glReadPixels it has perfomance comparable to virpipe (but higher).

~/gfx/build $ __EGL_VENDOR_LIBRARY_FILENAMES=/data/data/com.termux/files/usr/share/glvnd/egl_vendor.d/10_android_wrapper.json glmark2-es2 --fullscreen | grep -v -e "swap interval" -e "swap_control"
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      Imagination Technologies
    GL_RENDERER:    PowerVR Rogue GE8320
    GL_VERSION:     OpenGL ES 3.2 build 1.13@5776728
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   496x1100 fullscreen
=======================================================
Using memfd
draw resize
[build] use-vbo=false: FPS: 58 FrameTime: 17.536 ms
[build] use-vbo=true: FPS: 58 FrameTime: 17.318 ms
[texture] texture-filter=nearest: FPS: 57 FrameTime: 17.597 ms
[texture] texture-filter=linear: FPS: 55 FrameTime: 18.291 ms
[texture] texture-filter=mipmap: FPS: 57 FrameTime: 17.749 ms
[shading] shading=gouraud: FPS: 57 FrameTime: 17.721 ms
[shading] shading=blinn-phong-inf: FPS: 57 FrameTime: 17.832 ms
[shading] shading=phong: FPS: 56 FrameTime: 17.883 ms
[shading] shading=cel: FPS: 57 FrameTime: 17.569 ms
[bump] bump-render=high-poly: FPS: 56 FrameTime: 18.097 ms
[bump] bump-render=normals: FPS: 58 FrameTime: 17.439 ms
[bump] bump-render=height: FPS: 56 FrameTime: 18.084 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 56 FrameTime: 18.055 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 57 FrameTime: 17.850 ms
[pulsar] light=false:quads=5:texture=false: FPS: 57 FrameTime: 17.590 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 61 FrameTime: 16.641 ms
[desktop] effect=shadow:windows=4: FPS: 60 FrameTime: 16.948 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 59 FrameTime: 17.152 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 59 FrameTime: 17.071 ms
[jellyfish] <default>: FPS: 59 FrameTime: 17.154 ms
[terrain] <default>: FPS: 39 FrameTime: 26.277 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 57 FrameTime: 17.557 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 57 FrameTime: 17.850 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 56 FrameTime: 18.080 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 56 FrameTime: 18.096 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 57 FrameTime: 17.676 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 57 FrameTime: 17.751 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 57 FrameTime: 17.759 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 56 FrameTime: 18.008 ms
=======================================================
                                  glmark2 Score: 55 
=======================================================

But this is contrary to logic, perfomance with glReadPixels should be close to virpipe perfomance.

@twaik
Copy link
Contributor

twaik commented May 26, 2023

Maybe it is somehow related to waiting for rendering. After disabling both glReadPixels and sending xcb_present_pixmap_checked (replaced with real_eglSwapBuffers(nativeDisplay, Surface::getSurface((Surface*)surface));) I've got this log:

~/gfx/build $ __EGL_VENDOR_LIBRARY_FILENAMES=/data/data/com.termux/files/usr/share/glvnd/egl_vendor.d/10_android_wrapper.json glmark2-es2 --fullscreen | grep -v -e "swap interval" -e "swap_control"
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      Imagination Technologies
    GL_RENDERER:    PowerVR Rogue GE8320
    GL_VERSION:     OpenGL ES 3.2 build 1.13@5776728
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   496x1100 fullscreen
=======================================================
Using memfd
draw resize
[build] use-vbo=false: FPS: 464 FrameTime: 2.159 ms
[build] use-vbo=true: FPS: 1524 FrameTime: 0.656 ms
[texture] texture-filter=nearest: FPS: 3967 FrameTime: 0.252 ms
[texture] texture-filter=linear: FPS: 3963 FrameTime: 0.252 ms
[texture] texture-filter=mipmap: FPS: 3971 FrameTime: 0.252 ms
[shading] shading=gouraud: FPS: 1040 FrameTime: 0.962 ms
[shading] shading=blinn-phong-inf: FPS: 1069 FrameTime: 0.935 ms
[shading] shading=phong: FPS: 1007 FrameTime: 0.993 ms
[shading] shading=cel: FPS: 1003 FrameTime: 0.998 ms
[bump] bump-render=high-poly: FPS: 552 FrameTime: 1.813 ms
[bump] bump-render=normals: FPS: 3403 FrameTime: 0.294 ms
[bump] bump-render=height: FPS: 3275 FrameTime: 0.305 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 3721 FrameTime: 0.269 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 3741 FrameTime: 0.267 ms
[pulsar] light=false:quads=5:texture=false: FPS: 1913 FrameTime: 0.523 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 293 FrameTime: 3.418 ms
[desktop] effect=shadow:windows=4: FPS: 512 FrameTime: 1.954 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 118 FrameTime: 8.505 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 732 FrameTime: 1.367 ms
[jellyfish] <default>: FPS: 311 FrameTime: 3.225 ms
[terrain] <default>: FPS: 40 FrameTime: 25.171 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 1997 FrameTime: 0.501 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 2149 FrameTime: 0.466 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 2026 FrameTime: 0.494 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 2018 FrameTime: 0.496 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 2146 FrameTime: 0.466 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 1976 FrameTime: 0.506 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 2012 FrameTime: 0.497 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 2170 FrameTime: 0.461 ms
=======================================================
                                  glmark2 Score: 1830 
=======================================================

And for comparing I've tested my device with Android's native glmark2 and got this log:

05-26 21:11:49.285 30280 30300 I glmark2 : glmark2 2020.04
05-26 21:11:49.286 30280 30300 I glmark2 :     OpenGL Information
05-26 21:11:49.286 30280 30300 I glmark2 :     GL_VENDOR:     Imagination Technologies
05-26 21:11:49.286 30280 30300 I glmark2 :     GL_RENDERER:   PowerVR Rogue GE8320
05-26 21:11:49.286 30280 30300 I glmark2 :     GL_VERSION:    OpenGL ES 3.2 build 1.13@5776728
05-26 21:11:59.342 30280 30300 I glmark2 : [build] use-vbo=false: FPS: 439 FrameTime: 2.278 ms
05-26 21:12:09.366 30280 30300 I glmark2 : [build] use-vbo=true: FPS: 595 FrameTime: 1.681 ms
05-26 21:12:19.403 30280 30300 I glmark2 : [texture] texture-filter=nearest: FPS: 645 FrameTime: 1.550 ms
05-26 21:12:29.428 30280 30300 I glmark2 : [texture] texture-filter=linear: FPS: 661 FrameTime: 1.513 ms
05-26 21:12:39.455 30280 30300 I glmark2 : [texture] texture-filter=mipmap: FPS: 669 FrameTime: 1.495 ms
05-26 21:12:49.508 30280 30300 I glmark2 : [shading] shading=gouraud: FPS: 428 FrameTime: 2.336 ms
05-26 21:12:59.578 30280 30300 I glmark2 : [shading] shading=blinn-phong-inf: FPS: 400 FrameTime: 2.500 ms
05-26 21:13:09.654 30280 30300 I glmark2 : [shading] shading=phong: FPS: 298 FrameTime: 3.356 ms
05-26 21:13:19.734 30280 30300 I glmark2 : [shading] shading=cel: FPS: 275 FrameTime: 3.636 ms
05-26 21:13:29.882 30280 30300 I glmark2 : [bump] bump-render=high-poly: FPS: 214 FrameTime: 4.673 ms
05-26 21:13:39.996 30280 30300 I glmark2 : [bump] bump-render=normals: FPS: 538 FrameTime: 1.859 ms
05-26 21:13:50.075 30280 30300 I glmark2 : [bump] bump-render=height: FPS: 491 FrameTime: 2.037 ms
05-26 21:14:00.111 30280 30300 I glmark2 : [effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 309 FrameTime: 3.236 ms
05-26 21:14:10.185 30280 30300 I glmark2 : [effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 101 FrameTime: 9.901 ms
05-26 21:14:20.222 30280 30300 I glmark2 : [pulsar] light=false:quads=5:texture=false: FPS: 592 FrameTime: 1.689 ms
05-26 21:14:30.343 30280 30300 I glmark2 : [desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 135 FrameTime: 7.407 ms
05-26 21:14:40.392 30280 30300 I glmark2 : [desktop] effect=shadow:windows=4: FPS: 371 FrameTime: 2.695 ms
05-26 21:14:50.454 30280 30300 I glmark2 : [buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 128 FrameTime: 7.812 ms
05-26 21:15:00.491 30280 30300 I glmark2 : [buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 128 FrameTime: 7.812 ms
05-26 21:15:10.523 30280 30300 I glmark2 : [buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: FPS: 178 FrameTime: 5.618 ms
05-26 21:15:20.743 30280 30300 I glmark2 : [ideas] speed=duration: FPS: 369 FrameTime: 2.710 ms
05-26 21:15:31.099 30280 30300 I glmark2 : [jellyfish] <default>: FPS: 167 FrameTime: 5.988 ms
05-26 21:15:41.777 30280 30300 I glmark2 : [terrain] <default>: FPS: 27 FrameTime: 37.037 ms
05-26 21:15:52.016 30280 30300 I glmark2 : [shadow] <default>: FPS: 168 FrameTime: 5.952 ms
05-26 21:16:03.187 30280 30300 I glmark2 : [refract] <default>: FPS: 16 FrameTime: 62.500 ms
05-26 21:16:13.425 30280 30300 I glmark2 : [conditionals] fragment-steps=0:vertex-steps=0: FPS: 528 FrameTime: 1.894 ms
05-26 21:16:23.453 30280 30300 I glmark2 : [conditionals] fragment-steps=5:vertex-steps=0: FPS: 262 FrameTime: 3.817 ms
05-26 21:16:33.491 30280 30300 I glmark2 : [conditionals] fragment-steps=0:vertex-steps=5: FPS: 643 FrameTime: 1.555 ms
05-26 21:16:43.519 30280 30300 I glmark2 : [function] fragment-complexity=low:fragment-steps=5: FPS: 429 FrameTime: 2.331 ms
05-26 21:16:53.547 30280 30300 I glmark2 : [function] fragment-complexity=medium:fragment-steps=5: FPS: 214 FrameTime: 4.673 ms
05-26 21:17:03.593 30280 30300 I glmark2 : [loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 419 FrameTime: 2.387 ms
05-26 21:17:13.618 30280 30300 I glmark2 : [loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 417 FrameTime: 2.398 ms
05-26 21:17:23.645 30280 30300 I glmark2 : [loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 401 FrameTime: 2.494 ms
05-26 21:17:23.650 30280 30300 I glmark2 : glmark2 Score: 353

So as far as I see here busy waiting is a BIG problem, so we should use double buffering here and switch buffers on XCB_PRESENT_COMPLETE_NOTIFY. Blocking connection until we get XCB_PRESENT_COMPLETE_NOTIFY is a VERY bad idea. But I agree that it fits to a test case.

Thank you in advance.

@twaik
Copy link
Contributor

twaik commented May 26, 2023

Also I think we should call real_eglSwapBuffers(nativeDisplay, Surface::getSurface((Surface*)surface)); before glReadPixels. I've tried glFlush but it looks like it does not really finish all drawing operations (I am getting segfault in /vendor/lib64/egl/libGLESv2_mtk.so (glDrawArrays+2880)). Even if it will not really do something it will be low-cost and harmless.

@twaik
Copy link
Contributor

twaik commented May 26, 2023

Also (for fallback) we should not do glReadPixels until we get XCB_PRESENT_COMPLETE_NOTIFY. This way we will keep GL and rest of application running even if frame still was not rendered. But application will be able to wait for synchronization event (vblank?) using EGLSync mechanisms (which will be emulated/wrapped too).

@tareksander
Copy link
Owner Author

I implemented double buffering now, so we only have to wait for X if the last present took longer than rendering the next frame. Also I'm waiting for pixmap idle events instead now, so the present operation doesn't have to be complete. With that I get ~800fps in es2gears in the emulator. I'll se if I can modify it to only present in the last present finished, so we don't bother X with too many images, maybe that improves it further.

@tareksander
Copy link
Owner Author

Yep, not processing the buffer on the CPU when it's not needed has really improved things, now ~85000 fps in the emulator.

@tareksander
Copy link
Owner Author

tareksander commented May 28, 2023

Next I'll try to create a shared pixmap from an DMABUF fd. Can you try glmark again? In the emulator it gives me this error:

$ glmark2-es2
Error: Failed to find suitable EGL config
Error: Error: Couldn't get GL visual config!
Error: main: Could not initialize canvas

es2gears works, so the env variables are fine. I'll debug that later.

@tareksander
Copy link
Owner Author

Also I think we should call real_eglSwapBuffers(nativeDisplay, Surface::getSurface((Surface*)surface)); before glReadPixels. I've tried glFlush but it looks like it does not really finish all drawing operations (I am getting segfault in /vendor/lib64/egl/libGLESv2_mtk.so (glDrawArrays+2880)). Even if it will not really do something it will be low-cost and harmless.

glReadPixels should work as-is, quoting chapter 2.1 of the GLES2 spec: "Commands are always processed in the order in which they are received, although there may be an indeterminate delay before the effects of a command are realized. This means, for example, that one primitive must be drawn completely before any subsequent one can affect the framebuffer. It also means that queries and pixel read operations return state consistent with complete execution of all previously invoked GL commands. In general, the effects of a GL command on either GL modes or the framebuffer must be complete before any subsequent command can have any such effects."

@twaik
Copy link
Contributor

twaik commented May 28, 2023

Ok. Now glmark2-es2 reports highest FPS I've seen but the rendering is not smooth.

glmark2-es2 log
~/gfx-build $ DISPLAY=:0 glmark2-es2 --fullscreen
** Failed to set swap interval. Results may be bounded above by refresh rate.
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      Imagination Technologies
    GL_RENDERER:    PowerVR Rogue GE8320
    GL_VERSION:     OpenGL ES 3.2 build 1.13@5776728
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   496x1100 fullscreen
=======================================================
** Failed to set swap interval. Results may be bounded above by refresh rate.
[build] use-vbo=false: FPS: 285 FrameTime: 3.519 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[build] use-vbo=true: FPS: 1144 FrameTime: 0.874 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[texture] texture-filter=nearest: FPS: 2705 FrameTime: 0.370 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[texture] texture-filter=linear: FPS: 2706 FrameTime: 0.370 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[texture] texture-filter=mipmap: FPS: 2716 FrameTime: 0.368 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[shading] shading=gouraud: FPS: 786 FrameTime: 1.273 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[shading] shading=blinn-phong-inf: FPS: 802 FrameTime: 1.248 ms
[shading] shading=phong: FPS: 795 FrameTime: 1.259 ms
[shading] shading=cel: FPS: 794 FrameTime: 1.261 ms
[bump] bump-render=high-poly: FPS: 387 FrameTime: 2.585 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[bump] bump-render=normals: FPS: 2405 FrameTime: 0.416 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[bump] bump-render=height: FPS: 2282 FrameTime: 0.438 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 2684 FrameTime: 0.373 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 2633 FrameTime: 0.380 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[pulsar] light=false:quads=5:texture=false: FPS: 1243 FrameTime: 0.805 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 98 FrameTime: 10.292 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[desktop] effect=shadow:windows=4: FPS: 187 FrameTime: 5.371 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 54 FrameTime: 18.681 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
** Failed to set swap interval. Results may be bounded above by refresh rate.
[ideas] speed=duration: FPS: 246 FrameTime: 4.069 ms
[jellyfish] <default>: FPS: 223 FrameTime: 4.502 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[terrain] <default>: FPS: 21 FrameTime: 49.225 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
** Failed to set swap interval. Results may be bounded above by refresh rate.
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 1451 FrameTime: 0.689 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 1493 FrameTime: 0.670 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 1473 FrameTime: 0.679 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 1599 FrameTime: 0.626 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[function] fragment-complexity=medium:fragment-steps=5: FPS: 1465 FrameTime: 0.683 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 1472 FrameTime: 0.680 ms
** Failed to set swap interval. Results may be bounded above by refresh rate.
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 1507 FrameTime: 0.664 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 1603 FrameTime: 0.624 ms
=======================================================
                                  glmark2 Score: 1283 
=======================================================
Video
video_2023-05-28_21-04-35.mp4
Video
video_2023-05-28_21-04-38.mp4
Video
video_2023-05-28_21-04-40.mp4
Video
video_2023-05-28_21-04-43.mp4

Rendering was much more smooth with the old method, but it did not report high FPS.

@twaik
Copy link
Contributor

twaik commented May 28, 2023

Also about rendewrer name. Mesa's virpipe uses virgl ($originalName) for this. Can we use here something like termux-gfx-wrapper ($originalName)?

@tareksander
Copy link
Owner Author

Rendering was much more smooth with the old method, but it did not report high FPS.

Ok, I think I'll keep the new method as an option. Is there some way to predict the time window where a new frame has to be submitted for X11? Maybe that could be used to select an appropriate frame. The problem is that when we aren't bombarding X with frames, the time after the last frame completed and the next one is processed on the CPU could be too high with all the format conversion. With a bit of prediction you could select the approximate last frame that could still make it in time to X and render that.

Or maybe a proper triple buffering implementation would be better, to fully decouple the display timing from the rendering.

The other question is: do you even need 1000s of frames when X can only display 60 of them a second? It's reasonable that eglSwapBuffers can block, and that would also save CPU and GPU resources for everything else. So should VSync be an option, e.g. to old PresentNotify system? If an application needs rendering decoupled from the window system timings, it can use PBuffers or GLES FBOs.

Also about rendewrer name. Mesa's virpipe uses virgl ($originalName) for this. Can we use here something like termux-gfx-wrapper ($originalName)?

Fixed that.

@tareksander
Copy link
Owner Author

Next I'll work on HardwareBuffer rendering, which can eliminate the copy to the pixmap. And maybe also the format change, depending on available HardwareBuffer formats. But doing the format change in a shader instead should also be possible, and may be faster, depending on whether the memory bandwidth is the bottleneck or not.
Maybe that can smooth out the frames.

@twaik
Copy link
Contributor

twaik commented May 28, 2023

Ok, I think I'll keep the new method as an option. Is there some way to predict the time window where a new frame has to be submitted for X11?

Maybe timers. Currently X server draws image (or tries to) every 17 milliseconds (when possible).

The problem is that when we aren't bombarding X with frames, the time after the last frame completed and the next one is processed on the CPU could be too high with all the format conversion.

I thought about triple buffering. I thought about the following roles:

  1. Front buffer (where we currently drawing).
  2. Processing buffer (present_pixmap request is sent but response is not yet received).
  3. Back buffer (presemt pixmap request is send and response is received).

So when eglSwapBuffers receives PRESENT_COMPLETE_NOTIFY for current processing buffer it glReadPixelses current front buffer, converts it's format and sends present_pixmap request. I mean roles of buffers are shifted and now back buffer becomes front buffer, precessing buffer received response so it is a back buffer.

The other question is: do you even need 1000s of frames when X can only display 60 of them a second?

I think that is a target of SwapInterval feature. Currently we have SwapInterval = 0 for tests.

Fixed that.

I think you did not.

    GL_VENDOR:      Imagination Technologies
    GL_RENDERER:    PowerVR Rogue GE8320
    GL_VERSION:     OpenGL ES 3.2 build 1.13@5776728

@twaik
Copy link
Contributor

twaik commented May 28, 2023

Ok, I think I'll keep the new method as an option. Is there some way to predict the time window where a new frame has to be submitted for X11? Maybe that could be used to select an appropriate frame. The problem is that when we aren't bombarding X with frames, the time after the last frame completed and the next one is processed on the CPU could be too high with all the format conversion. With a bit of prediction you could select the approximate last frame that could still make it in time to X and render that.

Or maybe a proper triple buffering implementation would be better, to fully decouple the display timing from the rendering.

The other question is: do you even need 1000s of frames when X can only display 60 of them a second? It's reasonable that eglSwapBuffers can block, and that would also save CPU and GPU resources for everything else. So should VSync be an option, e.g. to old PresentNotify system? If an application needs rendering decoupled from the window system timings, it can use PBuffers or GLES FBOs.

Maybe we can ask Mesa people how it should work? I am pretty sure they know what's better.

@tareksander
Copy link
Owner Author

tareksander commented May 28, 2023

Fixed that.

I think you did not.

    GL_VENDOR:      Imagination Technologies
    GL_RENDERER:    PowerVR Rogue GE8320
    GL_VERSION:     OpenGL ES 3.2 build 1.13@5776728

Oh, you meant for GLES, not for EGL.
Fixed it for real now.

According to EGL spec a swap interval of 1 is the default, so normal vsync. I'll make that the default then when the testing is complete and properly implement eglSwapInterval for values 0 and 1.

I also made the env variable TERMUX_EGL_X11_MODE to override it for now. BLOCK forces vsync (old version, wait for present notify), IDLE just waits for pixmap idle notify (the new version).

Approximating the time to the next frame could work, finally an opportunity to apply some sliding average function I learned in university lol.

@twaik
Copy link
Contributor

twaik commented May 28, 2023

Wait. I thought Imagination Technologies is some kind of joke or easter egg for lols that you put into wrapper. But it looks like it is a real company and it is unmodified name loaded directly from vendor libraries. I like it :) .

@twaik
Copy link
Contributor

twaik commented May 29, 2023

For some reason eglinfo has segfault.

05-29 09:46:43.980 24792 24792 I crash_dump64: obtaining output fd from tombstoned, type: kDebuggerdTombstoneProto
05-29 09:46:43.983 24792 24792 I crash_dump64: performing dump of process 24787 (target tid = 24787)
05-29 09:46:44.165 24792 24792 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
05-29 09:46:44.165 24792 24792 F DEBUG   : Build fingerprint: 'samsung/a04exx/a04e:13/TP1A.220624.014/A042FXXS2CWC3:user/release-keys'
05-29 09:46:44.165 24792 24792 F DEBUG   : Revision: '0'
05-29 09:46:44.165 24792 24792 F DEBUG   : ABI: 'arm64'
05-29 09:46:44.165 24792 24792 F DEBUG   : Processor: '1'
05-29 09:46:44.165 24792 24792 F DEBUG   : Timestamp: 2023-05-29 09:46:43.999824671+0300
05-29 09:46:44.166 24792 24792 F DEBUG   : Process uptime: 2s
05-29 09:46:44.166 24792 24792 F DEBUG   : Cmdline: eglinfo
05-29 09:46:44.166 24792 24792 F DEBUG   : pid: 24787, tid: 24787, name: eglinfo  >>> eglinfo <<<
05-29 09:46:44.166 24792 24792 F DEBUG   : uid: 10270
05-29 09:46:44.166 24792 24792 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000001f03
05-29 09:46:44.166 24792 24792 F DEBUG   :     x0  0000000000001f03  x1  0000000000000000  x2  00000077b05a6230  x3  000000784b801648
05-29 09:46:44.166 24792 24792 F DEBUG   :     x4  0000000000000f03  x5  b40000784b8f6922  x6  6f74537865546c67  x7  754d443365676172
05-29 09:46:44.166 24792 24792 F DEBUG   :     x8  000000784f48fb80  x9  4cdf158a95659fe7  x10 000000784b800548  x11 00000000ffffffff
05-29 09:46:44.166 24792 24792 F DEBUG   :     x12 000000784b80170c  x13 b40000784b879a30  x14 0000000000000167  x15 0000000000000070
05-29 09:46:44.166 24792 24792 F DEBUG   :     x16 000000593b3acdd8  x17 000000784bd5aec0  x18 0000007851578000  x19 000000593b3b52a4
05-29 09:46:44.166 24792 24792 F DEBUG   :     x20 0000000000000000  x21 0000000000001f03  x22 000000593b3adeb0  x23 0000007851115010
05-29 09:46:44.166 24792 24792 F DEBUG   :     x24 000000593b3aea78  x25 000000593b3adea8  x26 0000000000000018  x27 000000593b3ade50
05-29 09:46:44.166 24792 24792 F DEBUG   :     x28 000000593b3adeac  x29 0000007fc78b0330
05-29 09:46:44.166 24792 24792 F DEBUG   :     lr  000000593b39c2d4  sp  0000007fc78b0330  pc  000000784bd5aed0  pst 0000000080000000
05-29 09:46:44.167 24792 24792 F DEBUG   : backtrace:
05-29 09:46:44.167 24792 24792 F DEBUG   :   NOTE: Function names and BuildId information is missing for some frames due
05-29 09:46:44.167 24792 24792 F DEBUG   :   NOTE: to unreadable libraries. For unwinds of apps, only shared libraries
05-29 09:46:44.167 24792 24792 F DEBUG   :   NOTE: found under the lib/ directory are readable.
05-29 09:46:44.167 24792 24792 F DEBUG   :   NOTE: On this device, run setenforce 0 to make the libraries readable.
05-29 09:46:44.167 24792 24792 F DEBUG   :   NOTE: Unreadable libraries:
05-29 09:46:44.167 24792 24792 F DEBUG   :   NOTE:   /data/data/com.termux/files/usr/bin/eglinfo
05-29 09:46:44.167 24792 24792 F DEBUG   :       #00 pc 0000000000086ed0  /apex/com.android.runtime/lib64/bionic/libc.so (__strlen_aarch64+16) (BuildId: 35a04626779868e5f2a30e171716818d)
05-29 09:46:44.167 24792 24792 F DEBUG   :       #01 pc 000000000005b2d0  /data/data/com.termux/files/usr/bin/eglinfo
05-29 09:46:44.167 24792 24792 F DEBUG   :       #02 pc 000000000005870c  /data/data/com.termux/files/usr/bin/eglinfo
05-29 09:46:44.167 24792 24792 F DEBUG   :       #03 pc 0000000000040d38  /data/data/com.termux/files/usr/bin/eglinfo
05-29 09:46:44.167 24792 24792 F DEBUG   :       #04 pc 000000000004031c  /data/data/com.termux/files/usr/bin/eglinfo
05-29 09:46:44.167 24792 24792 F DEBUG   :       #05 pc 000000000003fdd8  /data/data/com.termux/files/usr/bin/eglinfo
05-29 09:46:44.167 24792 24792 F DEBUG   :       #06 pc 0000000000085e10  /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+96) (BuildId: 35a04626779868e5f2a30e171716818d)
05-29 09:46:44.198 24792 24792 E crash_dump64: AM data write failed: Broken pipe

@tareksander
Copy link
Owner Author

Can you test what the last commit is that works for you? In the emulator it still works. Maybe it's the HardwareBuffer fd extraction test at the start? If it can crash, it would be better to just perform it at install and cache the result (and provide a way to re-run the test, in case a system update changes the behaviour).

@twaik
Copy link
Contributor

twaik commented May 29, 2023

Hmm...

EGL client extensions string:
    EGL_EXT_client_extensions, EGL_EXT_device_base, 
    EGL_EXT_device_enumeration, EGL_EXT_device_query, EGL_EXT_platform_base, 
    EGL_EXT_platform_device, EGL_EXT_platform_wayland, EGL_EXT_platform_x11, 
    EGL_EXT_platform_xcb, EGL_KHR_client_get_all_proc_addresses, 
    EGL_KHR_debug, EGL_KHR_platform_android, EGL_KHR_platform_gbm, 
    EGL_KHR_platform_wayland, EGL_KHR_platform_x11, EGL_MESA_platform_gbm, 
    EGL_MESA_platform_surfaceless

Android platform:
EGL API version: 1.4
EGL vendor string: Android
EGL version string: 1.4 Android META-EGL
EGL client APIs: OpenGL_ES
EGL extensions string:
    EGL_ANDROID_get_native_client_buffer, EGL_ANDROID_image_native_buffer, 
    EGL_KHR_image_base, EGL_KHR_platform_android

Thread 1 "eglinfo" received signal SIGSEGV, Segmentation fault.
0x0000007ff3d27250 in __strlen_aarch64 () from /apex/com.android.runtime/lib64/bionic/libc.so
(gdb) bt
#0  0x0000007ff3d27250 in __strlen_aarch64 () from /apex/com.android.runtime/lib64/bionic/libc.so
#1  0x00000055555ae3f4 in glad_gl_get_extensions (version=30002, out_exts=0x7fffffec00, out_num_exts_i=0x7fffffebfc, out_exts_i=0x7fffffebf0) at src/glad/src/gl.c:9873
#2  0x00000055555a9000 in glad_gl_find_extensions_gles2 (version=30002) at src/glad/src/gl.c:11136
#3  0x00000055555a5ed8 in gladLoadGLES2UserPtr (load=0x55555a2f44 <glad_gl_get_proc_from_userptr>, userptr=0x7f7320a9c8 <eglGetProcAddress>) at src/glad/src/gl.c:11504
#4  0x00000055555ae05c in gladLoadGLES2 (load=0x7f7320a9c8 <eglGetProcAddress>) at src/glad/src/gl.c:11644
#5  0x000000555557cf9c in createEGLContext (d=0x7f48efd420 <egl_wrapper::androidDisplay>, conf=0x7ff3803c00, api=12448, khr_create_context=0, core_profile=0, context_version=0x7fffffedbc)
    at src/egl/opengl/eglinfo.c:478
#6  0x000000555557c6fc in doOneDisplay (d=0x7f48efd420 <egl_wrapper::androidDisplay>, name=0x555555d248 "Android", opts=...) at src/egl/opengl/eglinfo.c:619
#7  0x000000555557bac8 in main (argc=1, argv=0x7fffffef88) at src/egl/opengl/eglinfo.c:864

It fails after this line.

@twaik
Copy link
Contributor

twaik commented May 29, 2023

`Interesting thing. Even a few things.
It reports

EGL vendor string: Android
EGL version string: 1.4 Android META-EGL

But I see you are returning modified values from wrapper.

Another thing.

~/demos $ strace ./eglinfo 2>&1 | grep openat | grep GL
openat(AT_FDCWD, "/data/data/com.termux/files/usr/lib/libEGL.so.1", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/data/data/com.termux/files/usr/lib/libGLdispatch.so.0", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/system/lib64/libEGL.so", O_RDONLY|O_CLOEXEC) = 32
openat(AT_FDCWD, "/system/lib64/libGLESv2.so", O_RDONLY|O_CLOEXEC) = 33
openat(AT_FDCWD, "/system/lib64/libGLESv1_CM.so", O_RDONLY|O_CLOEXEC) = 93
openat(AT_FDCWD, "/system/lib64/libGLESv3.so", O_RDONLY|O_CLOEXEC) = 94
openat(AT_FDCWD, "/system/lib64/libEGL.so", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/system/lib64/libGLESv2.so", O_RDONLY|O_CLOEXEC) = 3
openat(AT_FDCWD, "/vendor/lib64/egl/libGLES_mali.so", O_RDONLY|O_CLOEXEC) = 4
openat(AT_FDCWD, "/system/lib64/libEGL.so", O_RDONLY|O_CLOEXEC) = 6
openat(AT_FDCWD, "/system/lib64/libGLESv1_CM.so", O_RDONLY|O_CLOEXEC) = 6
openat(AT_FDCWD, "/system/lib64/libGLESv2.so", O_RDONLY|O_CLOEXEC) = 6
openat(AT_FDCWD, "/data/data/com.termux/files/usr/lib/libEGL_mesa.so.0", O_RDONLY|O_CLOEXEC) = 13

So it somehow links to termux's libEGL (which is glvnd), then it links to vendor libraries, but in the end it links to libEGL_mesa.so.0 and I do not really understand how it is possible.

Also it dlsyms to glGetStringi but you do not export that. I am checked if it has pointer to function and I am pretty sure it is real, maybe it is pointer of glvnd itself.

@twaik
Copy link
Contributor

twaik commented May 29, 2023

Can you test what the last commit is that works for you

As far as I can understand eglinfo never worked with gfx-wrapper. I tried to build every single version I found and eglinfo segfaults with all of them.

@tareksander
Copy link
Owner Author

The library loading is expected. libglvnd loads all vendor EGL libraries upfront. The wrapper then loads the system EGL, which in turn loads the system and vendor GLES libs. After that Mesa gets loaded. Libglvnd provides all EGL and GLES core functions, which it then dispatches to the current vendor.
Could you build eglinfo with debug info and use gdb to find out where in eglinfo it's crashing?

@twaik
Copy link
Contributor

twaik commented May 29, 2023

Could you build eglinfo with debug info and use gdb to find out where in eglinfo it's crashing?

#3 (comment)

@twaik
Copy link
Contributor

twaik commented May 29, 2023

termux-packages repo does not contain meson (or I simply did not find it) so I've built eglinfo like this.

~/build $ clang src/egl/opengl/eglinfo.c src/glad/src/gl.c src/util/glinfo_common.c src/glad/src/egl.c -Isrc/util -Isrc/glad/include -o eglinfo -ggdb

@twaik
Copy link
Contributor

twaik commented May 29, 2023

glad_glGetStringi returns some invalid pointer.

@tareksander
Copy link
Owner Author

I think it's because EGL returns an ES3 context because it's backwards compatible with ES2, glad recognizes that and tries to use glGetStringi, which is an ES3 function. I set the reported version to 2.0 now, you can try that fix. For me eglinfo just never tried to display gles info.

@tareksander
Copy link
Owner Author

Oh, and the EGL strings aren't wrapped, because eglinfo is specifically requesting the Android platform (saw that in your output just now), not X11. The Android platform is designed to be a passthrough as much as possible, though I guess wrapping these string wouldn't hurt.

@tareksander
Copy link
Owner Author

@twaik I finished HardwareBuffer surfaces now but the rendered content won't show up in X11, even when using glFlush. Using memset to fill the DMABUF fd with 0xff displays a white image correctly though. Is it just not working in the emulator, or do you get the same on hardware?

@twaik
Copy link
Contributor

twaik commented May 31, 2023

It works but glmark score is very low.

~ $ glmark2-es2 --fullscreen | grep -v -e "swap interval"
HAL_PIXEL_FORMAT_BGRA_8888: 1
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      termux-gfx-wrapper (Imagination Technologies)
    GL_RENDERER:    termux-gfx-wrapper (PowerVR Rogue GE8320)
    GL_VERSION:     OpenGL ES 2.0
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   696x1600 fullscreen
=======================================================
memfd available
[build] use-vbo=false: FPS: 11 FrameTime: 99.261 ms
[build] use-vbo=true: FPS: 11 FrameTime: 99.704 ms
[texture] texture-filter=nearest: FPS: 11 FrameTime: 99.422 ms
[texture] texture-filter=linear: FPS: 11 FrameTime: 98.289 ms
[texture] texture-filter=mipmap: FPS: 11 FrameTime: 97.506 ms
[shading] shading=gouraud: FPS: 11 FrameTime: 99.970 ms
[shading] shading=blinn-phong-inf: FPS: 11 FrameTime: 99.948 ms
[shading] shading=phong: FPS: 11 FrameTime: 99.775 ms
[shading] shading=cel: FPS: 10 FrameTime: 100.546 ms
[bump] bump-render=high-poly: FPS: 10 FrameTime: 100.326 ms
[bump] bump-render=normals: FPS: 10 FrameTime: 100.285 ms
[bump] bump-render=height: FPS: 10 FrameTime: 101.419 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 10 FrameTime: 100.184 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 10 FrameTime: 104.469 ms
[pulsar] light=false:quads=5:texture=false: FPS: 11 FrameTime: 98.367 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 11 FrameTime: 98.737 ms
[desktop] effect=shadow:windows=4: FPS: 11 FrameTime: 98.562 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 11 FrameTime: 98.781 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 11 FrameTime: 99.350 ms
[jellyfish] <default>: FPS: 10 FrameTime: 102.712 ms
[terrain] <default>: FPS: 7 FrameTime: 144.094 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 11 FrameTime: 99.161 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 11 FrameTime: 99.791 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 11 FrameTime: 99.274 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 11 FrameTime: 99.635 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 10 FrameTime: 101.048 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 11 FrameTime: 99.549 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 11 FrameTime: 99.652 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 10 FrameTime: 100.129 ms
=======================================================
                                  glmark2 Score: 9 
=======================================================

With idle mode it is lower too.

~ $ TERMUX_EGL_X11_MODE=IDLE glmark2-es2 --fullscreen | grep -v -e "swap interval"
HAL_PIXEL_FORMAT_BGRA_8888: 1
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      termux-gfx-wrapper (Imagination Technologies)
    GL_RENDERER:    termux-gfx-wrapper (PowerVR Rogue GE8320)
    GL_VERSION:     OpenGL ES 2.0
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   696x1600 fullscreen
=======================================================
memfd available
[build] use-vbo=false: FPS: 135 FrameTime: 7.433 ms
[build] use-vbo=true: FPS: 794 FrameTime: 1.261 ms
[texture] texture-filter=nearest: FPS: 1478 FrameTime: 0.677 ms
[texture] texture-filter=linear: FPS: 1466 FrameTime: 0.682 ms
[texture] texture-filter=mipmap: FPS: 1472 FrameTime: 0.680 ms
[shading] shading=gouraud: FPS: 575 FrameTime: 1.742 ms
[shading] shading=blinn-phong-inf: FPS: 583 FrameTime: 1.717 ms
[shading] shading=phong: FPS: 545 FrameTime: 1.837 ms
[shading] shading=cel: FPS: 543 FrameTime: 1.844 ms
[bump] bump-render=high-poly: FPS: 332 FrameTime: 3.014 ms
[bump] bump-render=normals: FPS: 1279 FrameTime: 0.782 ms
[bump] bump-render=height: FPS: 1292 FrameTime: 0.774 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 1439 FrameTime: 0.695 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 1404 FrameTime: 0.713 ms
[pulsar] light=false:quads=5:texture=false: FPS: 667 FrameTime: 1.500 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 46 FrameTime: 21.745 ms
[desktop] effect=shadow:windows=4: FPS: 115 FrameTime: 8.705 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 32 FrameTime: 32.180 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 138 FrameTime: 7.294 ms
[jellyfish] <default>: FPS: 129 FrameTime: 7.792 ms
[terrain] <default>: FPS: 15 FrameTime: 70.902 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 829 FrameTime: 1.206 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 862 FrameTime: 1.161 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 864 FrameTime: 1.158 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 853 FrameTime: 1.172 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 854 FrameTime: 1.172 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 854 FrameTime: 1.172 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 837 FrameTime: 1.196 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 921 FrameTime: 1.087 ms
=======================================================
                                  glmark2 Score: 735 
=======================================================

I'll check what can be wrong here.

@twaik
Copy link
Contributor

twaik commented Jun 1, 2023

Ok, I do not know what can be wrong here.
Also, can you please make uninstall option in cmake script? It is not really comfortable to use rm $PREFIX/share/glvnd/egl_vendor.d/10_android_wrapper.json or export __EGL_VENDOR_LIBRARY_FILENAMES="$PREFIX/share/glvnd/egl_vendor.d/50_mesa.json"

And can you please make eglSwapBuffer report success to suppress this warning?

** Failed to set swap interval. Results may be bounded above by refresh rate.

@tareksander
Copy link
Owner Author

I added an uninstall target now and fixed eglSwapInterval. I also disabled HardwareBuffer surfaces for now, as I can't easily test them.

@twaik
Copy link
Contributor

twaik commented Jun 1, 2023

I can give you remote access to my test device if you need.

@tareksander
Copy link
Owner Author

I found something: If I lock and unlock the HardwareBuffer, it works also in the emulator. That probably forces all changes to get applied to the mapped buffer. The performance is still low, and interestingly it goes down over time.

@twaik
Copy link
Contributor

twaik commented Jun 1, 2023

Actually in emulator GraphicBuffer (and AHardwareBuffer) are implemented with memfd or ashmem file descriptor. So the content of the texture is copied back and forth all the time. It is relevant for emulator, but not for real devices.

@tareksander
Copy link
Owner Author

Interesting, I thought in the emulator it would also use DMABUF, that explains that. I added the env variable TERMUX_EGL_DISABLE_HWBUF which disables hardware buffer if set, to easily test both implementations.

I also added a simple frame time estimation for PBuffer rendering. Could you try glmark again and see if the rendering is smoother?

@tareksander
Copy link
Owner Author

I also tried to optimize the HardwareBuffer surfaces a bit, you can see if that helped. Though they should still be upside-down in X, but at least the color should be right with the BGR format.

@twaik
Copy link
Contributor

twaik commented Jun 1, 2023

Maybe I miss something but in block mode perfomance seems to be same

~/build $ glmark2-es2 --fullscreen
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      termux-gfx-wrapper (Imagination Technologies)
    GL_RENDERER:    termux-gfx-wrapper (PowerVR Rogue GE8320)
    GL_VERSION:     OpenGL ES 2.0
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   696x1600 fullscreen
=======================================================
[build] use-vbo=false: FPS: 10 FrameTime: 100.349 ms
[build] use-vbo=true: FPS: 11 FrameTime: 99.036 ms
[texture] texture-filter=nearest: FPS: 11 FrameTime: 97.968 ms
[texture] texture-filter=linear: FPS: 11 FrameTime: 97.859 ms
[texture] texture-filter=mipmap: FPS: 11 FrameTime: 98.033 ms
[shading] shading=gouraud: FPS: 11 FrameTime: 99.683 ms
[shading] shading=blinn-phong-inf: FPS: 11 FrameTime: 99.841 ms
[shading] shading=phong: FPS: 10 FrameTime: 100.023 ms
[shading] shading=cel: FPS: 10 FrameTime: 100.120 ms
[bump] bump-render=high-poly: FPS: 10 FrameTime: 100.102 ms
[bump] bump-render=normals: FPS: 11 FrameTime: 99.497 ms
[bump] bump-render=height: FPS: 11 FrameTime: 99.832 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 11 FrameTime: 99.891 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 10 FrameTime: 104.354 ms
[pulsar] light=false:quads=5:texture=false: FPS: 11 FrameTime: 98.785 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 11 FrameTime: 97.962 ms
[desktop] effect=shadow:windows=4: FPS: 11 FrameTime: 98.359 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 11 FrameTime: 98.875 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 11 FrameTime: 99.507 ms
[jellyfish] <default>: FPS: 10 FrameTime: 102.725 ms
[terrain] <default>: FPS: 7 FrameTime: 144.000 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 11 FrameTime: 98.800 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 11 FrameTime: 99.852 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 11 FrameTime: 98.688 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 11 FrameTime: 99.532 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 10 FrameTime: 100.555 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 10 FrameTime: 100.311 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 10 FrameTime: 100.126 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 11 FrameTime: 99.802 ms
=======================================================
                                  glmark2 Score: 9 
=======================================================
~/build $ TERMUX_EGL_DISABLE_HWBUF=1 glmark2-es2 --fullscreen
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      termux-gfx-wrapper (Imagination Technologies)
    GL_RENDERER:    termux-gfx-wrapper (PowerVR Rogue GE8320)
    GL_VERSION:     OpenGL ES 2.0
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   696x1600 fullscreen
=======================================================
[build] use-vbo=false: FPS: 11 FrameTime: 99.513 ms
[build] use-vbo=true: FPS: 11 FrameTime: 99.138 ms
[texture] texture-filter=nearest: FPS: 11 FrameTime: 97.999 ms
[texture] texture-filter=linear: FPS: 11 FrameTime: 98.707 ms
[texture] texture-filter=mipmap: FPS: 11 FrameTime: 98.411 ms
[shading] shading=gouraud: FPS: 11 FrameTime: 99.896 ms
[shading] shading=blinn-phong-inf: FPS: 11 FrameTime: 99.485 ms
[shading] shading=phong: FPS: 10 FrameTime: 100.008 ms
[shading] shading=cel: FPS: 10 FrameTime: 100.087 ms
[bump] bump-render=high-poly: FPS: 11 FrameTime: 99.854 ms
[bump] bump-render=normals: FPS: 11 FrameTime: 99.762 ms
[bump] bump-render=height: FPS: 11 FrameTime: 99.861 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 11 FrameTime: 99.796 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 10 FrameTime: 103.630 ms
[pulsar] light=false:quads=5:texture=false: FPS: 11 FrameTime: 98.707 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 11 FrameTime: 99.130 ms
[desktop] effect=shadow:windows=4: FPS: 11 FrameTime: 98.007 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 11 FrameTime: 99.356 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 11 FrameTime: 99.266 ms
[jellyfish] <default>: FPS: 10 FrameTime: 102.951 ms
[terrain] <default>: FPS: 8 FrameTime: 142.441 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 11 FrameTime: 99.290 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 10 FrameTime: 100.063 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 11 FrameTime: 98.379 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 11 FrameTime: 99.636 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 10 FrameTime: 100.679 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 11 FrameTime: 99.862 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 11 FrameTime: 99.762 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 10 FrameTime: 100.029 ms
=======================================================
                                  glmark2 Score: 9 
=======================================================
Idle mode seems to be broken... And it also has low perfomance.
~/build $ TERMUX_EGL_X11_MODE=IDLE TERMUX_EGL_DISABLE_HWBUF=1 glmark2-es2 --fullscreen
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      termux-gfx-wrapper (Imagination Technologies)
    GL_RENDERER:    termux-gfx-wrapper (PowerVR Rogue GE8320)
    GL_VERSION:     OpenGL ES 2.0
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   696x1600 fullscreen
=======================================================
[build] use-vbo=false: FPS: 13 FrameTime: 77.610 ms
[build] use-vbo=true: FPS: 13 FrameTime: 77.563 ms
[texture] texture-filter=nearest: FPS: 13 FrameTime: 77.191 ms
[texture] texture-filter=linear: FPS: 13 FrameTime: 77.213 ms
[texture] texture-filter=mipmap: FPS: 13 FrameTime: 77.309 ms
[shading] shading=gouraud: FPS: 13 FrameTime: 78.510 ms
[shading] shading=blinn-phong-inf: FPS: 13 FrameTime: 78.988 ms
[shading] shading=phong: FPS: 13 FrameTime: 80.601 ms
[shading] shading=cel: FPS: 13 FrameTime: 81.061 ms
[bump] bump-render=high-poly: FPS: 13 FrameTime: 82.449 ms
[bump] bump-render=normals: FPS: 13 FrameTime: 78.439 ms
[bump] bump-render=height: FPS: 13 FrameTime: 79.392 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 13 FrameTime: 79.754 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 12 FrameTime: 88.412 ms
[pulsar] light=false:quads=5:texture=false: FPS: 13 FrameTime: 77.936 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 12 FrameTime: 83.672 ms
[desktop] effect=shadow:windows=4: FPS: 13 FrameTime: 78.800 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 12 FrameTime: 84.095 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 13 FrameTime: 80.271 ms
[jellyfish] <default>: FPS: 12 FrameTime: 88.505 ms
[terrain] <default>: FPS: 7 FrameTime: 147.255 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 13 FrameTime: 78.440 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 13 FrameTime: 80.770 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 13 FrameTime: 77.772 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 13 FrameTime: 78.996 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 13 FrameTime: 82.429 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 13 FrameTime: 79.411 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 13 FrameTime: 78.984 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 13 FrameTime: 79.366 ms
=======================================================
                                  glmark2 Score: 11 
=======================================================
~/build $ TERMUX_EGL_X11_MODE=IDLE glmark2-es2 --fullscreen
=======================================================
    glmark2 2023.01
=======================================================
    OpenGL Information
    GL_VENDOR:      termux-gfx-wrapper (Imagination Technologies)
    GL_RENDERER:    termux-gfx-wrapper (PowerVR Rogue GE8320)
    GL_VERSION:     OpenGL ES 2.0
    Surface Config: buf=32 r=8 g=8 b=8 a=8 depth=24 stencil=0 samples=0
    Surface Size:   696x1600 fullscreen
=======================================================
[build] use-vbo=false: FPS: 13 FrameTime: 77.588 ms
[build] use-vbo=true: FPS: 13 FrameTime: 77.788 ms
[texture] texture-filter=nearest: FPS: 13 FrameTime: 77.871 ms
[texture] texture-filter=linear: FPS: 13 FrameTime: 77.748 ms
[texture] texture-filter=mipmap: FPS: 13 FrameTime: 77.741 ms
[shading] shading=gouraud: FPS: 13 FrameTime: 78.982 ms
[shading] shading=blinn-phong-inf: FPS: 13 FrameTime: 79.616 ms
[shading] shading=phong: FPS: 13 FrameTime: 80.867 ms
[shading] shading=cel: FPS: 13 FrameTime: 81.653 ms
[bump] bump-render=high-poly: FPS: 13 FrameTime: 83.200 ms
[bump] bump-render=normals: FPS: 13 FrameTime: 79.355 ms
[bump] bump-render=height: FPS: 13 FrameTime: 79.534 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 13 FrameTime: 80.683 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 12 FrameTime: 89.250 ms
[pulsar] light=false:quads=5:texture=false: FPS: 13 FrameTime: 78.411 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4: FPS: 12 FrameTime: 85.106 ms
[desktop] effect=shadow:windows=4: FPS: 13 FrameTime: 79.934 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[buffer] columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata: FPS: 12 FrameTime: 85.548 ms
Error: Requested MapBuffer VBO update method but GL_OES_mapbuffer is not supported!
[buffer] columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map: Unsupported
[ideas] speed=duration: FPS: 13 FrameTime: 80.910 ms
[jellyfish] <default>: FPS: 12 FrameTime: 89.294 ms
[terrain] <default>: FPS: 7 FrameTime: 147.546 ms
Error: We do not have the depth texture extension!!!
[shadow] <default>: Unsupported
Error: We do not have the depth texture extension!!!
[refract] <default>: Unsupported
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 13 FrameTime: 78.538 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 13 FrameTime: 81.306 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 13 FrameTime: 77.885 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 13 FrameTime: 79.864 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 13 FrameTime: 82.978 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 13 FrameTime: 80.160 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS: 13 FrameTime: 79.808 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 13 FrameTime: 80.038 ms
=======================================================
                                  glmark2 Score: 11 
=======================================================

@tareksander
Copy link
Owner Author

Maybe I miss something but in block mode perfomance seems to be same

That was just a guess. I made it such that the gl framebuffer and renderbuffer objects get reused if possible instead of being recreated on every eglMakeCurrent.

Idle mode seems to be broken... And it also has low perfomance.

What exactly is broken? The same thing as before?

@twaik
Copy link
Contributor

twaik commented Jun 1, 2023

I mean idle mode has a bit better perfomance than a block mode. It was much better in earlier commits.

@twaik
Copy link
Contributor

twaik commented Jun 1, 2023

Maybe in this case would be better to use xcb_shm_put_pixels. You can avoid waiting by saving cookie of request and check if it was processed by invoking xcb_poll_for_reply(conn, cookie.sequense, &reply, &err). It will not be bound to actual screen refreshing but this way you will have much faster rendering to screen.

@twaik
Copy link
Contributor

twaik commented Jun 10, 2023

@tareksander I think you should check how mesa's src/vulkan/wsi/wsi_common_x11.c works. It is not related to EGL, but it can tell you how to handle frames.

@twaik
Copy link
Contributor

twaik commented Jun 10, 2023

Also there is interesting code in src/gallium/auxiliary/vl/vl_winsys_dri3.c. It is related to dri3 but still can be useful.

@twaik
Copy link
Contributor

twaik commented Jun 26, 2023

@tareksander maybe you can implement something like buffer queue? I can integrate it to termux-x11 and Xwayland/Xvfb/Xtigervnc of termux.

@tareksander
Copy link
Owner Author

What kind of buffer queue?

@twaik
Copy link
Contributor

twaik commented Jun 26, 2023

Like in Android. Surfaces in Android have buffer queues with Consumers and Producers. I am not sure I can describe it correctly. https://source.android.com/docs/core/graphics/arch-bq-gralloc . If you can implement using multiple buffers at once with changing buffers on demand it will make everything a bit more faster.

@twaik
Copy link
Contributor

twaik commented Jun 26, 2023

There is mechanism called SurfaceTexture which implements both consumers and producers. I see the way to use it without JNI (or emulate JNI without JVM) but there is a problem with interacting with server. It will require connecting directly to X server's Binder, but there is no documented way to register broadcast/intent receiver without real Context.

@licy183
Copy link

licy183 commented Jun 28, 2023

This fork of libhybris implements x11: https://github.com/gemian/libhybris

Hope that it is helpful for you...

@twaik
Copy link
Contributor

twaik commented Jun 28, 2023

Libhybris implements WSI using custom ANativeWindow implementation. We are avoiding this.

@twaik
Copy link
Contributor

twaik commented Jul 13, 2023

I think we should port this + this (mechanisms used in mesa's EGL) or this (used in vulkan). It should be faster and more reliable since it is native code of X11 implementations.

@twaik
Copy link
Contributor

twaik commented Mar 31, 2024

Hello. Is there any progress?

@tareksander
Copy link
Owner Author

I have the dispatch function generator finished now, including EGL extensions. Now I need to override the reported EGL extensions to the actually supported ones and the GLES version to fixed 2.0 for now and I can start testing. I'll copy the X11 implementation form the C version pretty much exactly, but without hardware buffers for now, but I'll add some performance improvements at the cost of GLES spec non-compliance, that can be tuned via env vars.

Optimizations:

  • Modifying the vertex shader returns to flip the axis if needed.
  • Modify the fragment shader to swap around the color order.

That may interfere with programs that use glReadPixels, so I want to use env vars to control this. However doing the format conversion directly on the graphics chip should perform better, and better than using several buffers and doing it in stages via post-processing. That is what I'll have to do in Vulkan, since SPIR-V shaders aren't really modifiable easily.

@tareksander
Copy link
Owner Author

I'm testing if the Android EGL passthrough works, but the emulator keeps crashing lol. Let's see if restarting my system helps, Nvidia drivers on Linux are a bit flaky sometimes.

@twaik
Copy link
Contributor

twaik commented Apr 9, 2024

Any crashlogs?

@tareksander
Copy link
Owner Author

First eglinfo -p android gives this in the console: /buildbot/src/android/emu-34-release/hardware/google/gfxstream/host/gl/glestranslator/GLES_V2/GLESv2Imp.cpp:glTexSubImage2D:3892 error 0x502.
Second one crashes and gives this:

0409 16:40:59.000945   14963 ColorBufferGl.cpp:1029] Failed to import external memory object with error: 1282
E0409 16:40:59.001235   14963 ColorBuffer.cpp:95] Failed to import memory to ColorBufferGl:223
F0409 16:40:59.002899   14963 FrameBuffer.cpp:1133] FATAL in createColorBufferWithHandleLocked, err code: 4300000000: Failed to create ColorBuffer:223 format:36194 framework-format:0 width:0 height:0
Received signal 6
#0 0x7f5c08aa0efa <unknown>
#1 0x7f5c08aa0a34 <unknown>
#2 0x7f5c0c05b050 <unknown>
#3 0x7f5c0c0a9e2c <unknown>
#4 0x7f5c0c05afb2 gsignal
#5 0x7f5c0c045472 abort
#6 0x7f5c0e06c6d6 <unknown>
#7 0x7f5c0e06c6a6 emugl::AbortMessage::~AbortMessage()
#8 0x7f5c000b91d2 gfxstream::FrameBuffer::createColorBufferWithHandleLocked()
#9 0x7f5c000b8e32 gfxstream::FrameBuffer::createColorBuffer()
#10 0x7f5c000dbe83 gfxstream::renderControl_decoder_context_t::decode()
#11 0x7f5c000a3657 gfxstream::RenderThread::main()
#12 0x7f5c0e017f7d android::base::Thread::thread_main()
#13 0x7f5c0c0a8134 <unknown>
#14 0x7f5c0c1287dc <unknown>
  r8: 00007f5b1a932d00  r9: 0000000000000073 r10: 0000000000000008 r11: 0000000000000246
 r12: 0000000000000006 r13: 00007f5b1a932d48 r14: 00007f5b1a932e48 r15: 0000562eff7afa40
  di: 0000000000003913  si: 0000000000003a73  bp: 00007f5b1a9376c0  bx: 0000000000003a73
  dx: 0000000000000006  ax: 0000000000000000  cx: 00007f5c0c0a9e2c  sp: 00007f5b1a932be0
  ip: 00007f5c0c0a9e2c efl: 0000000000000246 cgf: 002b000000000033 erf: 0000000000000000
 trp: 0000000000000000 msk: fffffffe7ffbfedf cr2: 0000000000000000
[end of stack trace]
Calling _exit(1). Core file will not be generated.

Seems like I have to fix whatever is wrong with the EGL calls, because it causes the host implementation to crash lol.

@twaik
Copy link
Contributor

twaik commented Apr 10, 2024

  • Try the format matching the X11 format, else fall back to CPU or GPU post-processing

Probably that is not very right since in that case you must flip bytes. But you can try to allocate AHardwareBuffer with format 5 (which stands for non-SDK AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM). I use it in Termux:X11 and it seems to be supported on all devices. Best choice for our case since it is compatible with GLES textures and does not need separate convert processing.

@twaik
Copy link
Contributor

twaik commented Apr 10, 2024

I am not so sure but probably combining the new ability of Termux:X11 to use AHardwareBuffers + using AHARDWAREBUFFER_USAGE_CPU_READ_RARELY + AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER flags (without using AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN or AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN) may improve performance.

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