flypig.co.uk

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 RSS feed Click the icon for the Gecko-dev Diary RSS feed.

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.
(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 &quot;Compositor&quot; 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 &quot;Compositor&quot; 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 &quot;Compositor&quot; 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 &quot;Compositor&quot; 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 &quot;Compositor&quot; 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 &quot;CreateFallbackSurface&quot; 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 &quot;GLContextEGL::GetBufferAge&quot; 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 &quot;GLContextEGL::CreateWaylandBufferSurface&quot; 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 &quot;CreateEGLSurfaceImpl&quot; not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b GLContextProviderEGL::DestroyEGLSurface
Function &quot;GLContextProviderEGL::DestroyEGLSurface&quot; 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 &quot;Compositor&quot; 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 &quot;Compositor&quot; 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 &quot;Compositor&quot; 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 &quot;Compositor&quot; 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 &quot;Compositor&quot; 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