flypig.co.uk

List items

Items from the current list are shown below.

Blog

8 Apr 2024 : Day 210 #
I hope you'll forgive the fact it's a bit of a long diary entry today. If I were writing this properly I'd split the content up across a couple of days, but that wouldn't reflect what I'm actually doing. I'm not sure why I care about matching with reality, except to give a more honest reflection of what I'm actually doing. As with all of these diary entries, you won't miss anything if you skip the debugger output, skim the text, or frankly just skip the entire entry!

There were a couple of tasks (well, three if I'm honest) left over on my to-do list from yesterday. The first was to compare the two library creation executions on ESR 78 and ESR 91.

I've been doing that throughout the day today. It was quite a lengthy process and there were some odd changes. Like the fact that on ESR 78 two sets of EGL client extensions get initialised, each of which includes a call to MarkExtensions() with a particular prefix. The prefixes are "client" and "display":
  MarkExtensions(rawExtString, shouldDumpExts, "client", 
    &mAvailableExtensions);
[...]
  MarkExtensions(rawExtString, shouldDumpExts, "display", 
    &mAvailableExtensions);
On ESR 91 the initialisation process, which is quite similar in most other respects, does this differently, instead only initialising extensions with the "lib" prefix during the GLLibraryEGL::Init() method and then initialising extensions with the "display" prefix in the EglDisplay constructor:
  MarkExtensions(rawExtString, shouldDumpExts, "display", 
    sEGLExtensionNames, &mAvailableExtensions);
[...]
  MarkExtensions(rawExtString, shouldDumpExts, "lib", 
    sEGLLibraryExtensionNames, &mAvailableExtensions);
To be honest, I'm not really sure what this MarkExtensions() method is really needed for (I've read the code; it didn't really enlighten me), so I don't know whether this is a really significant difference or not. I'm going to hope not for the moment.

The other big difference is that in GLLibraryEGL::DoEnsureInitialized() there's a call, about half way through the initialisation, to CreateDisplay():
  mEGLDisplay = CreateDisplay(forceAccel, gfxInfo, out_failureId, aDisplay);
  if (!mEGLDisplay) {
    return false;
  }
This has been removed in ESR 91 and now happens in the GLLibraryEGL::DefaultDisplay() method instead. What this means is that rather than being created during the library initialisation, it gets created the first time the default display is requested. This changes the order of things and, while I don't think it amounts to a practical difference, I could be wrong. Ordering can sometimes be crucial.

Other than these I don't notice any other significant differences between the two initialisation processes.

Next up is the task of checking every instance where the display is used, with the aim of checking what it's set to in each case. While in ESR 78 the display value is used widely in the GLContextEGL class, it's primarily used to pass in to library methods. We saw that when we were stepping through the code on Day 207. In contrast ESR 91 moves the display variable directly in to the library calls. For example, In ESR 78 we have this — in my opinion — hideous use of non-bracketed code where the EGLDisplay dpy parameter is passed in:
          EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
                                           const EGLint* attrib_list) const
      WRAP(fCreatePbufferSurface(dpy, config, attrib_list))
Compare this to the ESR 91 code, where the display value is now a class variable and so no longer needs to be passed on. Thankfully the brackets and indentation have been sorted out as well:
  EGLSurface fCreatePbufferSurface(EGLConfig config,
                                   const EGLint* attrib_list) const {
    return mLib->fCreatePbufferSurface(mDisplay, config, attrib_list);
  }
The consequence is that while the value for the display must be passed in when library methods are called in the ESR 78 code like this:
  surface = egl->fCreatePbufferSurface(egl->Display(), config, &pbattrs[0]);
In the ESR 91 code there's no need to pass the value in. We have this instead:
  EGLSurface surface = egl.fCreatePbufferSurface(config, pbattrs.data());
It's actually a nice change and simplifies the code greatly. But it makes our comparison harder. I've had to put breakpoints on all of the library methods as a result. Here's the full list:
GLContextEGL::GetWSIInfo
GLContextEGL::CreateGLContext
CreateEmulatorBufferSurface
EglDisplay::fTerminate
EglDisplay::fMakeCurrent
EglDisplay::fDestroyContext
EglDisplay::fCreateContext
EglDisplay::fDestroySurface
EglDisplay::fCreateWindowSurface
EglDisplay::fCreatePbufferSurface
EglDisplay::fCreatePbufferFromClientBuffer
EglDisplay::fChooseConfig
EglDisplay::fGetConfigAttrib
EglDisplay::fGetConfigs
EglDisplay::fSwapBuffers
EglDisplay::fBindTexImage
EglDisplay::fReleaseTexImage
EglDisplay::fSwapInterval
EglDisplay::fCreateImage
EglDisplay::fDestroyImage
EglDisplay::fQuerySurface
EglDisplay::fQuerySurfacePointerANGLE
EglDisplay::fCreateSync
EglDisplay::fDestroySync
EglDisplay::fClientWaitSync
EglDisplay::fGetSyncAttrib
EglDisplay::fWaitSync
EglDisplay::fDupNativeFenceFDANDROID
EglDisplay::fQueryDisplayAttribEXT
EglDisplay::fCreateStreamKHR
EglDisplay::fDestroyStreamKHR
EglDisplay::fQueryStreamKHR
EglDisplay::fStreamConsumerGLTextureExternalKHR
EglDisplay::fStreamConsumerAcquireKHR
EglDisplay::fStreamConsumerReleaseKHR
EglDisplay::fStreamConsumerGLTextureExternalAttribsNV
EglDisplay::fCreateStreamProducerD3DTextureANGLE
EglDisplay::fStreamPostD3DTextureANGLE
EglDisplay::fSwapBuffersWithDamage
EglDisplay::fSetDamageRegion
And here's the output resulting from my putting breakpoints on them. Please forgive the long and rather dull output here, but I'm trying to follow the same processes as on Day 207, which means sharing the same output here as well. Note that many of the breakpoints simply don't stick:
(gdb) b GLContextEGL::GetWSIInfo
Breakpoint 10 at 0x7ff1105558: file 
gfx/gl/GLContextProviderEGL.cpp, line 692.
(gdb) b GLContextEGL::CreateGLContext
Breakpoint 11 at 0x7ff112d8d0: file 
gfx/gl/GLContextProviderEGL.cpp, line 742.
(gdb) b CreateEmulatorBufferSurface
Breakpoint 12 at 0x7ff111d2c8: file 
gfx/gl/GLContextProviderEGL.cpp, line 980.
(gdb) b EglDisplay::fTerminate
Breakpoint 13 at 0x7ff111baf0: file 
gfx/gl/GLLibraryEGL.h, line 234.
(gdb) b EglDisplay::fMakeCurrent
Breakpoint 14 at 0x7ff1104a04: EglDisplay::fMakeCurrent. (2 locations)
(gdb) b EglDisplay::fDestroyContext
Breakpoint 15 at 0x7ff112f4b0: file 
gfx/gl/GLLibraryEGL.h, line 242.
(gdb) b EglDisplay::fCreateContext
Breakpoint 16 at 0x7ff11098c8: file 
gfx/gl/GLLibraryEGL.h, line 248.
(gdb) b EglDisplay::fDestroySurface
Breakpoint 17 at 0x7ff1104a20: EglDisplay::fDestroySurface. (2 locations)
(gdb) b EglDisplay::fCreateWindowSurface
Breakpoint 18 at 0x7ff11182ac: file gfx/gl/GLLibraryEGL.h, line 259.
(gdb) b EglDisplay::fCreatePbufferSurface
Breakpoint 19 at 0x7ff1109ef8: file gfx/gl/GLLibraryEGL.h, line 265.
(gdb) b EglDisplay::fCreatePbufferFromClientBuffer
Function "EglDisplay::fCreatePbufferFromClientBuffer" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fChooseConfig
Breakpoint 20 at 0x7ff1109bd8: EglDisplay::fChooseConfig. (2 locations)
(gdb) b EglDisplay::fGetConfigAttrib
Breakpoint 21 at 0x7ff110bf44: EglDisplay::fGetConfigAttrib. (5 locations)
(gdb) b EglDisplay::fGetConfigs
Function "EglDisplay::fGetConfigs" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fSwapBuffers
Breakpoint 22 at 0x7ff110ba70: file gfx/gl/GLLibraryEGL.h, line 303.
(gdb) b EglDisplay::fBindTexImage
Breakpoint 23 at 0x7ff1104ad0: file gfx/gl/GLLibraryEGL.h, line 324.
(gdb) b EglDisplay::fReleaseTexImage
Breakpoint 24 at 0x7ff1104a68: file gfx/gl/GLLibraryEGL.h, line 329.
(gdb) b EglDisplay::fSwapInterval
Breakpoint 25 at 0x7ff112e1dc: file gfx/gl/GLLibraryEGL.h, line 706.
(gdb) b EglDisplay::fCreateImage
Function "EglDisplay::fCreateImage" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fDestroyImage
Function "EglDisplay::fDestroyImage" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fQuerySurface
Breakpoint 26 at 0x7ff110751c: file gfx/gl/GLLibraryEGL.h, line 348.
(gdb) b EglDisplay::fQuerySurfacePointerANGLE
Function "EglDisplay::fQuerySurfacePointerANGLE" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fCreateSync
Function "EglDisplay::fCreateSync" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fDestroySync
Function "EglDisplay::fDestroySync" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fClientWaitSync
Function "EglDisplay::fClientWaitSync" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fGetSyncAttrib
Function "EglDisplay::fGetSyncAttrib" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fWaitSync
Function "EglDisplay::fWaitSync" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fDupNativeFenceFDANDROID
Function "EglDisplay::fDupNativeFenceFDANDROID" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fQueryDisplayAttribEXT
Function "EglDisplay::fQueryDisplayAttribEXT" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fCreateStreamKHR
Function "EglDisplay::fCreateStreamKHR" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fDestroyStreamKHR
Function "EglDisplay::fDestroyStreamKHR" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fQueryStreamKHR
Function "EglDisplay::fQueryStreamKHR" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fStreamConsumerGLTextureExternalKHR
Function "EglDisplay::fStreamConsumerGLTextureExternalKHR" not 
    defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fStreamConsumerAcquireKHR
Function "EglDisplay::fStreamConsumerAcquireKHR" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fStreamConsumerReleaseKHR
Function "EglDisplay::fStreamConsumerReleaseKHR" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fStreamConsumerGLTextureExternalAttribsNV
Function "EglDisplay::fStreamConsumerGLTextureExternalAttribsNV" not 
    defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fCreateStreamProducerD3DTextureANGLE
Function "EglDisplay::fCreateStreamProducerD3DTextureANGLE" not 
    defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fStreamPostD3DTextureANGLE
Function "EglDisplay::fStreamPostD3DTextureANGLE" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) b EglDisplay::fSwapBuffersWithDamage
Breakpoint 27 at 0x7ff110bc3c: file gfx/gl/GLLibraryEGL.h, line 448.
(gdb) b EglDisplay::fSetDamageRegion
Function "EglDisplay::fSetDamageRegion" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) r
[...]
With that done the next step is to hop carefully through the code from breakpoint to breakpoint. The important thing to note here is that the display values exhibit the same behaviour as in ESR 78: they're all the same value and all set to 0x01. Once again this is a long and rather dull piece of debugger output; I've actually cut out a big portion since everything ends up looking the same.
Thread 38 "Compositor" hit Breakpoint 20, mozilla::gl::EglDisplay::
    fChooseConfig (num_config=0x7f1f96efb4, config_size=1, configs=0x7f1f96efc0,
    attrib_list=0x7edc004de8, this=0x7edc003590)
    at gfx/gl/GLLibraryEGL.h:679
679         return mLib->fChooseConfig(mDisplay, attrib_list, configs, 
    config_size,
(gdb) p mDisplay
$1 = (const EGLDisplay) 0x1
(gdb) c
Continuing.

Thread 38 "Compositor" hit Breakpoint 19, mozilla::gl::EglDisplay::
    fCreatePbufferSurface (attrib_list=0x7edc003cc8, config=0x555599bb50,
    this=0x7edc003590)
    at gfx/gl/GLLibraryEGL.h:666
666         return mLib->fCreatePbufferSurface(mDisplay, config, attrib_list);
(gdb) p /x mDisplay
$2 = 0x1
(gdb) c
Continuing.

Thread 38 "Compositor" hit Breakpoint 11, mozilla::gl::GLContextEGL::
    CreateGLContext (
    egl=std::shared_ptr<mozilla::gl::EglDisplay> (use count 4, weak count 2) = 
    {...}, desc=..., config=config@entry=0x555599bb50,
    surface=surface@entry=0x7edc004b60, useGles=useGles@entry=false, 
    out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at gfx/gl/GLContextProviderEGL.cpp:742
742         nsACString* const out_failureId) {
(gdb) p /x egl->mDisplay
$3 = 0x1
(gdb) c
Continuing.

[...]

Thread 38 &quot;Compositor&quot; hit Breakpoint 14, mozilla::gl::EglDisplay::
    fMakeCurrent (ctx=0x7edc004be0, read=0x7edc004b60, draw=0x7edc004b60,
    this=0x7edc003590)
    at gfx/gl/GLLibraryEGL.h:643
643         return mLib->fMakeCurrent(mDisplay, draw, read, ctx);
(gdb) p /x mDisplay
$9 = 0x1
(gdb) c
Continuing.
[New Thread 0x7f1f3bd7e0 (LWP 23890)]
=============== Preparing offscreen rendering context ===============
[New Thread 0x7f1f1bc7e0 (LWP 23891)]
[New Thread 0x7f1f17b7e0 (LWP 23892)]

[...]

Thread 38 &quot;Compositor&quot; hit Breakpoint 14, mozilla::gl::EglDisplay::
    fMakeCurrent (ctx=0x7edc004be0, read=0x7edc004b60, draw=0x7edc004b60,
    this=0x7edc003590)
    at gfx/gl/GLLibraryEGL.h:643
643         return mLib->fMakeCurrent(mDisplay, draw, read, ctx);
(gdb) p /x mDisplay
$10 = 0x1
(gdb) c
Continuing.
[Thread 0x7f1f3bd7e0 (LWP 23890) exited]
[...]
That all looks healthy to me. I'm happy to see this, even if it means there's not a problem to fix, it makes me more confident that the initialisation steps are working as intended. The EGL display value, at least, seems to be set and used correctly.

While stepping through the code I was surprised to see GLContextEGL::CreateGLContext() being called twice on ESR 91. This made me a little suspicious, so I checked to see whether the same thing is happening on ESR 78.

It is. This still feels odd to me, but it's consistent across the two versions so presumably correct.

Here are the breakpoints that get hit on ESR 78:
Thread 36 &quot;Compositor&quot; hit Breakpoint 1, mozilla::gl::GLContextEGL::
    CreateGLContext (egl=egl@entry=0x7eac0036a0, 
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    caps=..., isOffscreen=isOffscreen@entry=true, 
    config=config@entry=0x55558c8450, surface=surface@entry=0x7eac004170, 
    useGles=useGles@entry=false, out_failureId=out_failureId@entry=0x7fa512d378)
    at gfx/gl/GLContextProviderEGL.cpp:719
719         nsACString* const out_failureId) {
(gdb) bt
#0  mozilla::gl::GLContextEGL::CreateGLContext (egl=egl@entry=0x7eac0036a0, 
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    caps=..., isOffscreen=isOffscreen@entry=true, 
    config=config@entry=0x55558c8450, surface=surface@entry=0x7eac004170, 
    useGles=useGles@entry=false, 
    out_failureId=out_failureId@entry=0x7fa512d378)
    at gfx/gl/GLContextProviderEGL.cpp:719
#1  0x0000007fb8e6f244 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContextImpl (out_failureId=0x7fa512d378, 
    aUseGles=false, minCaps=..., 
    size=..., flags=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE)
    at gfx/gl/GLContextProviderEGL.cpp:1360
#2  mozilla::gl::GLContextEGL::CreateEGLPBufferOffscreenContextImpl (
    flags=<optimized out>, size=..., minCaps=..., aUseGles=<optimized out>, 
    out_failureId=0x7fa512d378) at gfx/gl/GLContextProviderEGL.cpp:1302
#3  0x0000007fb8e6f398 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContext (
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    size=..., minCaps=..., out_failureId=out_failureId@entry=0x7fa512d378)
    at gfx/gl/GLContextProviderEGL.cpp:1377
#4  0x0000007fb8e6f41c in mozilla::gl::GLContextProviderEGL::CreateHeadless (
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    out_failureId=out_failureId@entry=0x7fa512d378)
    at gfx/gl/GLContextProviderEGL.cpp:1391
[...]
#29 0x0000007fbe70b89c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/
    clone.S:78
(gdb) c
Continuing.

Thread 36 &quot;Compositor&quot; hit Breakpoint 1, mozilla::gl::GLContextEGL::
    CreateGLContext (egl=egl@entry=0x7eac0036a0, 
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    caps=..., isOffscreen=isOffscreen@entry=true, 
    config=config@entry=0x55558c8450, surface=surface@entry=0x7eac004170, 
    useGles=useGles@entry=true, out_failureId=out_failureId@entry=0x7fa512d378)
    at gfx/gl/GLContextProviderEGL.cpp:719
719         nsACString* const out_failureId) {
(gdb) bt
#0  mozilla::gl::GLContextEGL::CreateGLContext (egl=egl@entry=0x7eac0036a0, 
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    caps=..., isOffscreen=isOffscreen@entry=true, 
    config=config@entry=0x55558c8450, surface=surface@entry=0x7eac004170, 
    useGles=useGles@entry=true, 
    out_failureId=out_failureId@entry=0x7fa512d378)
    at gfx/gl/GLContextProviderEGL.cpp:719
#1  0x0000007fb8e6f244 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContextImpl (out_failureId=0x7fa512d378, 
    aUseGles=true, minCaps=..., 
    size=..., flags=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE)
    at gfx/gl/GLContextProviderEGL.cpp:1360
#2  mozilla::gl::GLContextEGL::CreateEGLPBufferOffscreenContextImpl (
    flags=<optimized out>, size=..., minCaps=..., aUseGles=<optimized out>, 
    out_failureId=0x7fa512d378) at gfx/gl/GLContextProviderEGL.cpp:1302
#3  0x0000007fb8e6f3c4 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContext (
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    size=..., minCaps=..., out_failureId=out_failureId@entry=0x7fa512d378)
    at gfx/gl/GLContextProviderEGL.cpp:1380
#4  0x0000007fb8e6f41c in mozilla::gl::GLContextProviderEGL::CreateHeadless (
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    out_failureId=out_failureId@entry=0x7fa512d378)
    at gfx/gl/GLContextProviderEGL.cpp:1391
[...]
#29 0x0000007fbe70b89c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/
    clone.S:78
(gdb) c
Continuing.
[New Thread 0x7fa4afe9a0 (LWP 3400)]
=============== Preparing offscreen rendering context ===============
[...]
And here are the same breakpoints getting hit on ESR 91. As you can see, the backtraces are similar in both cases. These all seems to be legit.
Thread 37 &quot;Compositor&quot; hit Breakpoint 28, mozilla::gl::GLContextEGL::
    CreateGLContext (
    egl=std::shared_ptr<mozilla::gl::EglDisplay> (use count 4, weak count 2) = 
    {...}, desc=..., config=config@entry=0x55558f7d10, 
    surface=surface@entry=0x7ed8004b60, useGles=useGles@entry=false, 
    out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at gfx/gl/GLContextProviderEGL.cpp:742
742         nsACString* const out_failureId) {
(gdb) bt
#0  mozilla::gl::GLContextEGL::CreateGLContext (egl=std::shared_ptr<mozilla::gl:
    :EglDisplay> (use count 4, weak count 2) = {...}, desc=..., 
    config=config@entry=0x55558f7d10, surface=surface@entry=0x7ed8004b60, 
    useGles=useGles@entry=false, out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at gfx/gl/GLContextProviderEGL.cpp:742
#1  0x0000007ff112e674 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContextImpl (
    egl=std::shared_ptr<mozilla::gl::EglDisplay> (use count 4, weak count 2) = 
    {...}, desc=..., size=..., useGles=useGles@entry=false, 
    out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at include/c++/8.3.0/ext/atomicity.h:96
#2  0x0000007ff112e7e4 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContext (
    display=std::shared_ptr<mozilla::gl::EglDisplay> (use count 4, weak count 
    2) = {...}, desc=..., size=..., 
    out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at include/c++/8.3.0/ext/atomicity.h:96
#3  0x0000007ff112e9b8 in mozilla::gl::GLContextProviderEGL::CreateHeadless (
    desc=..., out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at include/c++/8.3.0/ext/atomicity.h:96
#4  0x0000007ff112f260 in mozilla::gl::GLContextProviderEGL::CreateOffscreen (
    size=..., minCaps=..., 
    flags=flags@entry=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, 
    out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at gfx/gl/GLContextProviderEGL.cpp:1476
[...]
#26 0x0000007ff6a0289c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/
    clone.S:78
(gdb) c
Continuing.

Thread 37 &quot;Compositor&quot; hit Breakpoint 28, mozilla::gl::GLContextEGL::
    CreateGLContext (
    egl=std::shared_ptr<mozilla::gl::EglDisplay> (use count 4, weak count 2) = 
    {...}, desc=..., config=config@entry=0x55558f7d10, 
    surface=surface@entry=0x7ed8004b60, useGles=useGles@entry=true, 
    out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at gfx/gl/GLContextProviderEGL.cpp:742
742         nsACString* const out_failureId) {
(gdb) bt
#0  mozilla::gl::GLContextEGL::CreateGLContext (egl=std::shared_ptr<mozilla::gl:
    :EglDisplay> (use count 4, weak count 2) = {...}, desc=..., 
    config=config@entry=0x55558f7d10, surface=surface@entry=0x7ed8004b60, 
    useGles=useGles@entry=true, out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at gfx/gl/GLContextProviderEGL.cpp:742
#1  0x0000007ff112e674 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContextImpl (
    egl=std::shared_ptr<mozilla::gl::EglDisplay> (use count 4, weak count 2) = 
    {...}, desc=..., size=..., useGles=useGles@entry=true, 
    out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at include/c++/8.3.0/ext/atomicity.h:96
#2  0x0000007ff112e888 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContext (
    display=std::shared_ptr<mozilla::gl::EglDisplay> (use count 4, weak count 
    2) = {...}, desc=..., size=..., 
    out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at include/c++/8.3.0/ext/atomicity.h:96
#3  0x0000007ff112e9b8 in mozilla::gl::GLContextProviderEGL::CreateHeadless (
    desc=..., out_failureId=out_failureId@entry=0x7f1f96f1c8)
    at include/c++/8.3.0/ext/atomicity.h:96
[...]
#26 0x0000007ff6a0289c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/
    clone.S:78
(gdb) c
Continuing.
[New Thread 0x7f1f3fe7e0 (LWP 28609)]
=============== Preparing offscreen rendering context ===============
[...]
Since I now have breakpoints set on GLContextEGL::CreateGLContext(), as a final task for today, I thought I'd look at the inputs passed in to the method and stored within the GLContextEGL object. The creation methods are both pretty small and straightforward. Here's what happen when we inspect the values on ESR 78:
Thread 36 &quot;Compositor&quot; hit Breakpoint 4, mozilla::gl::GLContext::
    GLContext (this=this@entry=0x7eac109140, 
    flags=mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE, caps=..., 
    sharedContext=sharedContext@entry=0x0, isOffscreen=true, 
    useTLSIsCurrent=useTLSIsCurrent@entry=false) at gfx/gl/GLContext.cpp:274
274     GLContext::GLContext(CreateContextFlags flags, const SurfaceCaps& caps,
(gdb) p flags
$12 = mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE
(gdb) p caps
$13 = (const mozilla::gl::SurfaceCaps &) @0x7fa516f210: {any = true, color = 
    true, alpha = false, bpp16 = false, depth = false, stencil = false, 
  premultAlpha = true, preserve = false, surfaceAllocator = {mRawPtr = 0x0}}
(gdb) p sharedContext
$14 = (mozilla::gl::GLContext *) 0x0
(gdb) p isOffscreen
$15 = true
(gdb) p useTLSIsCurrent
$16 = false
(gdb) 
On ESR 91 things are a little different. The flags and isOffscreen values are passed in as part of a GLContextDesc object rather than being passed in as separate parameters. That's not too hard to unravel for comparison. But more tricky is the fact that there's no caps parameter at all. That's because this gets set in the GLContext::InitOffscreen() method instead. To properly compare the values we need to therefore check this method as well:
Thread 38 &quot;Compositor&quot; hit Breakpoint 30, mozilla::gl::GLContext::
    GLContext (this=this@entry=0x7edc19aa50, desc=..., 
    sharedContext=sharedContext@entry=0x0, 
    useTLSIsCurrent=useTLSIsCurrent@entry=false)
    at gfx/gl/GLContext.cpp:283
283     GLContext::GLContext(const GLContextDesc& desc, GLContext* 
    sharedContext,
(gdb) p desc.flags
$26 = mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE
(gdb) p sharedContext
$27 = (mozilla::gl::GLContext *) 0x0
(gdb) p desc.isOffscreen
$28 = true
(gdb) p useTLSIsCurrent
$29 = false
(gdb) p desc
$30 = (const mozilla::gl::GLContextDesc &) @0x7f1f930020: {<mozilla::gl::
    GLContextCreateDesc> = {
    flags = mozilla::gl::CreateContextFlags::REQUIRE_COMPAT_PROFILE}, 
    isOffscreen = true}
(gdb) c
Continuing.

Thread 38 &quot;Compositor&quot; hit Breakpoint 31, mozilla::gl::GLContext::
    InitOffscreen (this=this@entry=0x7edc19aa50, size=..., caps=...)
    at gfx/gl/GLContext.cpp:2424
2424                                  const SurfaceCaps& caps) {
(gdb) p caps
$31 = (const mozilla::gl::SurfaceCaps &) @0x7f1f930158: {any = false, color = 
    true, alpha = false, bpp16 = false, depth = false, stencil = false, 
  premultAlpha = true, preserve = false, surfaceAllocator = {mRawPtr = 0x0}}
(gdb) n
2425      if (!CreateScreenBuffer(size, caps)) return false;
[...]
(gdb) n
2437      return true;
(gdb) p mScreen.mTuple.mFirstA.mCaps
$38 = {any = false, color = true, alpha = false, bpp16 = false, depth = false, 
    stencil = false, premultAlpha = true, preserve = false, 
  surfaceAllocator = {mRawPtr = 0x0}}
$39 = {any = false, color = true, alpha = false, bpp16 = false, depth = false, 
    stencil = false, premultAlpha = true, preserve = false, 
  surfaceAllocator = {mRawPtr = 0x0}}
(gdb) 
The conclusion of the above is that although storage of the different parameters happens in slightly different places, the result is ultimately the same. The values stored as part of GLContext match across ESR 78 and ESR 91. On the one hand this isn't surprising: by now I've spent quite a bit of effort doing my best to get them to align. On the other hand it's also surprising: quite a lot of effort has been needed to get them to align, so there's been plenty of scope for errors.

To my eye, even though the initialisation flows of ESR 78 and ESR 91 are different, it looks to me like the same things get executed largely in the same order and the various relevant objects end up in a similar state.

Where does this leave things? It means that it's probably time to move on from the render initialisation process and take a look at the page rendering process instead. I'd still also like to get some kind of confirmation that if something were being rendered it would show on screen. You may recall I tried to do this a while back by changing the background colour of the screen clearing calls. This didn't yield good results, so I'll need to put some thought into an alternative method to show me what I need. I'll have to think about that 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