Gecko-dev Diary
Starting in August 2023 I'll be upgrading the Sailfish OS browser from Gecko version ESR 78 to ESR 91. This page catalogues my progress.
Latest code changes are in the gecko-dev sailfishos-esr91 branch.
There is an index of all posts in case you want to jump to a particular day.
Gecko
5 most recent items
5 Apr 2024 : Day 207 #
Today I'm continuing to step through the two different versions of the WebView app I'm testing with. I'm particularly interested in the value set for the EGL display variable. I'm concerned that this isn't being set properly and, if that's the case, that would be a serious hindrance to having a working render.
First up I'm going to set a breakpoint on the GetAppDisplay() method. This is the method that's supposed to tie the EGL display — where rending takes place — to the Qt display interface. Hopefully the execution and usage will be similar across the two versions. But let's see.
First up these are the places the method gets called when running the ESR 78 code.
So let's perform the same process but this time using the ESR 91 build for comparison:
Moreover, the CreateHeadless() method is itself being called from GLContextProviderEGL::CreateOffscreen(). Recall that this is the place where the GetAppDisplay() method was being called from in ESR 78. So all of these calls are happening in close proximity of one another.
I'm going to put the analysis of this to one side for now and come back to it. The next question to figure out is what the value being returned by the method is.
I'm not able to extract this from inside the GetAppDisplay() method because of the way the method is structured. But the method returns the value that I'm interested in. In all cases this value gets immediately passed in to another method, so if I can breakpoint on the method it gets passed to I can then extract the value from the input parameters of the method.
On ESR 78 the relevant method is the following. Notice how it has an aDisplay parameter. That's the parameter we're interested in.
Let's compare that to ESR 91. This time there are two breakpoints to add and we want to extract the values from both, assuming they hit.
The difference between the two is concerning. The ESR 78 execution is particularly problematic because there are two values being generated and right now it's not clear which one is actually being used. In order to make progress I need to understand this better.
My plan is to go through each instance of egl->Display() or mEgl->Display() in GLContextProviderEGL.cpp and add a breakpoint to the method containing it so that we can check its value. This will have two purposes. First it will help to understand the flow of execution: which methods should be called and which are unused. Second it will allow me to test what the value of the display is in each case.
You might ask why I don't just place a breakpoint on EGLLibrary::Display() and watch the values flow in. Well, I tried and the breakpoint won't stick. There is some benefit to doing it the hard way, which is that I'm getting to review all of the places in the code where it's used. If I'd taken the easy route I would have missed that opportunity.
Here are the methods that make use of the Display() value. I'm going to place a breakpoint on every single one and record every single usage until the page is completely rendered.
If you'd like to read any of my other gecko diary entries, they're all available on my Gecko-dev Diary page.
First up I'm going to set a breakpoint on the GetAppDisplay() method. This is the method that's supposed to tie the EGL display — where rending takes place — to the Qt display interface. Hopefully the execution and usage will be similar across the two versions. But let's see.
First up these are the places the method gets called when running the ESR 78 code.
(gdb) b GetAppDisplay Function "GetAppDisplay" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (GetAppDisplay) pending. (gdb) r Starting program: /usr/bin/harbour-webview [...] Thread 36 "Compositor" hit Breakpoint 1, mozilla::gl::GetAppDisplay () at gfx/gl/GLContextProviderEGL.cpp:175 175 static EGLDisplay GetAppDisplay() { (gdb) bt #0 mozilla::gl::GetAppDisplay () at gfx/gl/GLContextProviderEGL.cpp:175 #1 0x0000007fb8e81a2c in mozilla::gl::GLContextProviderEGL::CreateOffscreen ( size=..., minCaps=..., flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, out_failureId=out_failureId@entry=0x7fa516f378) at gfx/gl/GLContextProviderEGL.cpp:1404 #2 0x0000007fb8ee275c in mozilla::layers::CompositorOGL::CreateContext ( this=0x7eac003420) at gfx/layers/opengl/CompositorOGL.cpp:250 #3 mozilla::layers::CompositorOGL::CreateContext (this=0x7eac003420) at gfx/layers/opengl/CompositorOGL.cpp:223 #4 0x0000007fb8f033bc in mozilla::layers::CompositorOGL::Initialize ( this=0x7eac003420, out_failureReason=0x7fa516f730) at gfx/layers/opengl/CompositorOGL.cpp:374 #5 0x0000007fb8fdaf7c in mozilla::layers::CompositorBridgeParent:: NewCompositor (this=this@entry=0x7f8c99d8f0, aBackendHints=...) at gfx/layers/ipc/CompositorBridgeParent.cpp:1534 [...] #25 0x0000007fbe70b89c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/ clone.S:78 (gdb) c Continuing. [New Thread 0x7fa4afe9a0 (LWP 5119)] =============== Preparing offscreen rendering context =============== [...]From this we can see it only gets called once in the GLContextProviderEGL::CreateOffscreen() method. We're also interested in the value it gets set to and that's going to be the next thing to look at. But first off I just want to compare how often the method gets called and where from.
So let's perform the same process but this time using the ESR 91 build for comparison:
(gdb) b GetAppDisplay Function "GetAppDisplay" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (GetAppDisplay) pending. (gdb) r Starting program: /usr/bin/harbour-webview [...] Thread 37 "Compositor" hit Breakpoint 1, mozilla::gl::GetAppDisplay () at gfx/gl/GLContextProviderEGL.cpp:161 161 static EGLDisplay GetAppDisplay() { (gdb) handle SIGPIPE nostop Signal Stop Print Pass to program Description SIGPIPE No Yes Yes Broken pipe (gdb) bt #0 mozilla::gl::GetAppDisplay () at gfx/gl/GLContextProviderEGL.cpp:161 #1 0x0000007ff112e910 in mozilla::gl::GLContextProviderEGL::CreateHeadless ( desc=..., out_failureId=out_failureId@entry=0x7f1f5ac1c8) at gfx/gl/GLContextProviderEGL.cpp:1434 #2 0x0000007ff112f260 in mozilla::gl::GLContextProviderEGL::CreateOffscreen ( size=..., minCaps=..., flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, out_failureId=out_failureId@entry=0x7f1f5ac1c8) at gfx/gl/GLContextProviderEGL.cpp:1476 #3 0x0000007ff1197d40 in mozilla::layers::CompositorOGL::CreateContext ( this=this@entry=0x7ed8002f10) at gfx/layers/opengl/CompositorOGL.cpp:254 #4 0x0000007ff11ad520 in mozilla::layers::CompositorOGL::Initialize ( this=0x7ed8002f10, out_failureReason=0x7f1f5ac520) at gfx/layers/opengl/CompositorOGL.cpp:391 #5 0x0000007ff12c31fc in mozilla::layers::CompositorBridgeParent:: NewCompositor (this=this@entry=0x7fc4b77630, aBackendHints=...) at gfx/layers/ipc/CompositorBridgeParent.cpp:1493 [...] #24 0x0000007ff6a0289c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/ clone.S:78 (gdb) c Continuing. Thread 37 "Compositor" hit Breakpoint 1, mozilla::gl::GetAppDisplay () at gfx/gl/GLContextProviderEGL.cpp:161 161 static EGLDisplay GetAppDisplay() { (gdb) bt #0 mozilla::gl::GetAppDisplay () at gfx/gl/GLContextProviderEGL.cpp:161 #1 0x0000007ff111907c in mozilla::gl::DefaultEglLibrary ( out_failureId=out_failureId@entry=0x7f1f5ac1c8) at gfx/gl/GLContextProviderEGL.cpp:1519 #2 0x0000007ff112e920 in mozilla::gl::DefaultEglDisplay (aDisplay=0x1, out_failureId=0x7f1f5ac1c8) at gfx/gl/GLContextEGL.h:29 #3 mozilla::gl::GLContextProviderEGL::CreateHeadless (desc=..., out_failureId=out_failureId@entry=0x7f1f5ac1c8) at gfx/gl/GLContextProviderEGL.cpp:1434 #4 0x0000007ff112f260 in mozilla::gl::GLContextProviderEGL::CreateOffscreen ( size=..., minCaps=..., flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, out_failureId=out_failureId@entry=0x7f1f5ac1c8) at gfx/gl/GLContextProviderEGL.cpp:1476 #5 0x0000007ff1197d40 in mozilla::layers::CompositorOGL::CreateContext ( this=this@entry=0x7ed8002f10) at gfx/layers/opengl/CompositorOGL.cpp:254 #6 0x0000007ff11ad520 in mozilla::layers::CompositorOGL::Initialize ( this=0x7ed8002f10, out_failureReason=0x7f1f5ac520) at gfx/layers/opengl/CompositorOGL.cpp:391 #7 0x0000007ff12c31fc in mozilla::layers::CompositorBridgeParent:: NewCompositor (this=this@entry=0x7fc4b77630, aBackendHints=...) at gfx/layers/ipc/CompositorBridgeParent.cpp:1493 [...] #26 0x0000007ff6a0289c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/ clone.S:78 Continuing. [New Thread 0x7f1f1fe7e0 (LWP 16054)] =============== Preparing offscreen rendering context =============== [...]This time the breakpoint hits twice. First the method is called from GLContextProviderEGL::CreateHeadless(). Soon after it's called from DefaultEglLibrary(). But as it happens this itself is being called from GLContextProviderEGL::CreateHeadless(). So it shouldn't be too hard to follow this through and figure out why it's getting called twice instead of once.
Moreover, the CreateHeadless() method is itself being called from GLContextProviderEGL::CreateOffscreen(). Recall that this is the place where the GetAppDisplay() method was being called from in ESR 78. So all of these calls are happening in close proximity of one another.
I'm going to put the analysis of this to one side for now and come back to it. The next question to figure out is what the value being returned by the method is.
I'm not able to extract this from inside the GetAppDisplay() method because of the way the method is structured. But the method returns the value that I'm interested in. In all cases this value gets immediately passed in to another method, so if I can breakpoint on the method it gets passed to I can then extract the value from the input parameters of the method.
On ESR 78 the relevant method is the following. Notice how it has an aDisplay parameter. That's the parameter we're interested in.
/* static */ bool GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId, EGLDisplay aDisplay);We have two different methods to consider on ESR 91. Note again how they both have aDisplay parameters. Those are the parameters we need to check.
RefPtr<GLLibraryEGL> GLLibraryEGL::Create(nsACString* const out_failureId, EGLDisplay aDisplay) inline std::shared_ptr<EglDisplay> DefaultEglDisplay(nsACString* const out_failureId, EGLDisplay aDisplay);So, here goes with the ESR 78 build. I've placed a breakpoint on the method so we can extract the parameter.
(gdb) b GLLibraryEGL::EnsureInitialized Breakpoint 2 at 0x7fb8e6ee78: file obj-build-mer-qt-xr/dist/include/mozilla/ StaticPtr.h, line 152. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /usr/bin/harbour-webview [...] Thread 36 "Compositor" hit Breakpoint 2, mozilla::gl::GLLibraryEGL:: EnsureInitialized (forceAccel=false, out_failureId=0x7fa516f378, aDisplay=0x1) at obj-build-mer-qt-xr/dist/include/mozilla/StaticPtr.h:152 152 obj-build-mer-qt-xr/dist/include/mozilla/StaticPtr.h: No such file or directory. (gdb) p /x aDisplay $1 = 0x1 (gdb) c Continuing. Thread 36 "Compositor" hit Breakpoint 2, mozilla::gl::GLLibraryEGL:: EnsureInitialized (forceAccel=false, out_failureId=0x7fa516f378, aDisplay=0x0) at obj-build-mer-qt-xr/dist/include/mozilla/StaticPtr.h:152 152 in obj-build-mer-qt-xr/dist/include/mozilla/StaticPtr.h (gdb) p /x aDisplay $2 = 0x0 (gdb) c Continuing. Thread 36 "Compositor" hit Breakpoint 2, mozilla::gl::GLLibraryEGL:: EnsureInitialized (forceAccel=false, out_failureId=0x7fa516f378, aDisplay=0x0) at obj-build-mer-qt-xr/dist/include/mozilla/StaticPtr.h:152 152 in obj-build-mer-qt-xr/dist/include/mozilla/StaticPtr.h (gdb) p /x aDisplay $3 = 0x0 (gdb)As can be seen it actually hits this breakpoint three times. The first time the aDisplay value is set to 0x1. Subsequent calls have the value 0x0 passed on.
Let's compare that to ESR 91. This time there are two breakpoints to add and we want to extract the values from both, assuming they hit.
(gdb) b GLLibraryEGL::Create Breakpoint 1 at 0x7ff1118e8c: file gfx/gl/GLLibraryEGL.cpp, line 343. (gdb) b DefaultEglDisplay Breakpoint 2 at 0x7ff112e914: file gfx/gl/GLContextEGL.h, line 29. (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /usr/bin/harbour-webview [...] Thread 38 "Compositor" hit Breakpoint 2, mozilla::gl:: DefaultEglDisplay (aDisplay=0x1, out_failureId=0x7f1f94c1c8) at gfx/gl/GLContextEGL.h:29 29 const auto lib = DefaultEglLibrary(out_failureId); (gdb) p /x aDisplay $1 = 0x1 (gdb) c Continuing. Thread 38 "Compositor" hit Breakpoint 1, mozilla::gl::GLLibraryEGL:: Create (out_failureId=out_failureId@entry=0x7f1f94c1c8, aDisplay=0x1) at gfx/gl/GLLibraryEGL.cpp:343 343 RefPtr<GLLibraryEGL> GLLibraryEGL::Create(nsACString* const out_failureId, EGLDisplay aDisplay) { (gdb) p /x aDisplay $2 = 0x1 (gdb)There are two hits, one for each of our breakpoints. Both are being passed a display value of 0x1.
The difference between the two is concerning. The ESR 78 execution is particularly problematic because there are two values being generated and right now it's not clear which one is actually being used. In order to make progress I need to understand this better.
My plan is to go through each instance of egl->Display() or mEgl->Display() in GLContextProviderEGL.cpp and add a breakpoint to the method containing it so that we can check its value. This will have two purposes. First it will help to understand the flow of execution: which methods should be called and which are unused. Second it will allow me to test what the value of the display is in each case.
You might ask why I don't just place a breakpoint on EGLLibrary::Display() and watch the values flow in. Well, I tried and the breakpoint won't stick. There is some benefit to doing it the hard way, which is that I'm getting to review all of the places in the code where it's used. If I'd taken the easy route I would have missed that opportunity.
Here are the methods that make use of the Display() value. I'm going to place a breakpoint on every single one and record every single usage until the page is completely rendered.
DestroySurface() CreateFallbackSurface() CreateSurfaceFromNativeWindow() GLContextEGLFactory::CreateImpl() GLContextEGL::GLContextEGL() GLContextEGL::~GLContextEGL() GLContextEGL::BindTexImage() GLContextEGL::ReleaseTexImage() GLContextEGL::MakeCurrentImpl() GLContextEGL::RenewSurface() GLContextEGL::SwapBuffers() GLContextEGL::GetWSIInfo() GLContextEGL::GetBufferAge() GLContextEGL::CreateGLContext() GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo() GLContextEGL::CreateWaylandBufferSurface() CreateEmulatorBufferSurface() CreateConfig() CreateEGLSurfaceImpl() GLContextProviderEGL::DestroyEGLSurface() GetAttrib() ChooseConfigOffscreen() GLContextEGL::CreateEGLPBufferOffscreenContextImpl()Here goes!
(gdb) b CreateFallbackSurface Function "CreateFallbackSurface" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) b CreateSurfaceFromNativeWindow Breakpoint 2 at 0x7fb8e673a8: CreateSurfaceFromNativeWindow. (2 locations) (gdb) b GLContextEGLFactory::CreateImpl Breakpoint 3 at 0x7fb8e6f460: file gfx/gl/GLContextProviderEGL.cpp, line 372. (gdb) b GLContextEGL::GLContextEGL Breakpoint 4 at 0x7fb8e67a98: file gfx/gl/GLContextProviderEGL.cpp, line 472. (gdb) b GLContextEGL::~GLContextEGL Breakpoint 5 at 0x7fb8e81668: GLContextEGL::~GLContextEGL. (2 locations) (gdb) b GLContextEGL::BindTexImage Breakpoint 6 at 0x7fb8e66328: GLContextEGL::BindTexImage. (2 locations) (gdb) b GLContextEGL::ReleaseTexImage Breakpoint 7 at 0x7fb8e663a8: GLContextEGL::ReleaseTexImage. (2 locations) (gdb) b GLContextEGL::MakeCurrentImpl Breakpoint 8 at 0x7fb8e66420: GLContextEGL::MakeCurrentImpl. (2 locations) (gdb) b GLContextEGL::RenewSurface Breakpoint 9 at 0x7fb8e67358: GLContextEGL::RenewSurface. (2 locations) (gdb) b GLContextEGL::SwapBuffers Breakpoint 10 at 0x7fb8e6ae40: file gfx/gl/GLContextProviderEGL.cpp, line 643. (gdb) b GLContextEGL::GetWSIInfo Breakpoint 11 at 0x7fb8e65da0: file gfx/gl/GLContextProviderEGL.cpp, line 674. (gdb) b GLContextEGL::GetBufferAge Function "GLContextEGL::GetBufferAge" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) b GLContextEGL::CreateGLContext Breakpoint 12 at 0x7fb8e69ef0: file gfx/gl/GLContextProviderEGL.cpp, line 719. (gdb) b GLContextEGL::CreatePBufferSurfaceTryingPowerOfTwo Breakpoint 13 at 0x7fb8e6bf80: file gfx/gl/GLContextProviderEGL.cpp, line 854. (gdb) b GLContextEGL::CreateWaylandBufferSurface Function "GLContextEGL::CreateWaylandBufferSurface" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) b CreateEmulatorBufferSurface Breakpoint 14 at 0x7fb8e67b40: file gfx/gl/GLContextProviderEGL.cpp, line 953. (gdb) b CreateConfig Breakpoint 15 at 0x7fb8e6a498: CreateConfig. (5 locations) (gdb) b CreateEGLSurfaceImpl Function "CreateEGLSurfaceImpl" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) b GLContextProviderEGL::DestroyEGLSurface Function "GLContextProviderEGL::DestroyEGLSurface" not defined. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) b GetAttrib Breakpoint 16 at 0x7fb8e6ab64: GetAttrib. (4 locations) (gdb) b ChooseConfigOffscreen Breakpoint 17 at 0x7fb8e6a920: file gfx/gl/GLContextProviderEGL.cpp, line 1265. (gdb) b GLContextEGL::CreateEGLPBufferOffscreenContextImpl Breakpoint 18 at 0x7fb8e6f130: GLContextEGL:: CreateEGLPBufferOffscreenContextImpl. (2 locations) (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /usr/bin/harbour-webview [...]That's all of the breakpoints set. Or at least, all that it was possible to make stick. The obvious thing for me to copy over now is the places where the breakpoint actually hit. But there are a lot of them and going through them is very laborious, so I'll just include a selection to give you a flavour.
Thread 38 "Compositor" hit Breakpoint 18, mozilla::gl::GLContextEGL:: CreateEGLPBufferOffscreenContextImpl ( flags=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, size=..., minCaps=..., aUseGles=false, out_failureId=0x7fa55eb378) at gfx/gl/GLContextProviderEGL.cpp:1305 1305 nsACString* const out_failureId) { (gdb) n 1309 if (!GLLibraryEGL::EnsureInitialized(forceEnableHardware, out_failureId)) { (gdb) n Thread 38 "Compositor" hit Breakpoint 18, mozilla::gl::GLContextEGL:: CreateEGLPBufferOffscreenContextImpl (out_failureId=0x7fa55eb378, aUseGles=false, minCaps=..., size=..., flags=mozilla::gl::CreateContextFlags:: REQUIRE_COMPAT_PROFILE) at gfx/gl/GLContextProviderEGL.cpp:1313 1313 auto* egl = gl::GLLibraryEGL::Get(); (gdb) n 20 struct SurfaceCaps final { (gdb) p /x egl->mEGLDisplay $2 = 0x1 (gdb) c Continuing. Thread 38 "Compositor" hit Breakpoint 17, mozilla::gl:: ChooseConfigOffscreen (egl=egl@entry=0x7eac0036a0, flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, minCaps=..., aUseGles=aUseGles@entry=false, useWindow=useWindow@entry=false, out_configCaps=out_configCaps@entry=0x7fa55eb210) at gfx/gl/GLContextProviderEGL.cpp:1265 1265 SurfaceCaps* const out_configCaps) { (gdb) n 1266 nsTArray<EGLint> configAttribList; (gdb) p /x egl->mEGLDisplay $3 = 0x1 (gdb) c Continuing. [...] Thread 38 "Compositor" hit Breakpoint 8, mozilla::gl::GLContextEGL:: MakeCurrentImpl (this=0x7eac108cd0) at gfx/gl/GLContextProviderEGL.cpp:571 571 EGLSurface surface = (gdb) p /x mEgl.mRawPtr->mEGLDisplay $21 = 0x1 (gdb) c Continuing. [New Thread 0x7fa4afe9a0 (LWP 19251)] =============== Preparing offscreen rendering context =============== [New Thread 0x7fae9649a0 (LWP 19252)] [Thread 0x7fa50ee9a0 (LWP 12902) exited] [Thread 0x7fa51ff9a0 (LWP 12872) exited] [Thread 0x7fa512f9a0 (LWP 12900) exited] [New Thread 0x7fae86d9a0 (LWP 19253)] [New Thread 0x7fa48fd9a0 (LWP 19254)] [New Thread 0x7fa48bc9a0 (LWP 19255)] [New Thread 0x7fa487b9a0 (LWP 19256)] [New Thread 0x7fa512f9a0 (LWP 19257)] Thread 38 "Compositor" hit Breakpoint 8, mozilla::gl::GLContextEGL:: MakeCurrentImpl (this=0x7eac108cd0) at gfx/gl/GLContextProviderEGL.cpp:571 571 EGLSurface surface = (gdb) p /x mEgl.mRawPtr->mEGLDisplay $22 = 0x1 (gdb) c Continuing. [Thread 0x7fa4afe9a0 (LWP 19251) exited] [...]Phew. One thing we can see from this is that every actual use of the display is set to 0x1. That's true for the onces I cut out as well. Now we have to check the same thing on ESR 91. It's a bit late to do that tonight, but it'll be first thing on my to-do list tomorrow.
If you'd like to read any of my other gecko diary entries, they're all available on my Gecko-dev Diary page.
Comments
Uncover Disqus comments