flypig.co.uk

List items

Items from the current list are shown below.

Blog

21 Apr 2024 : Day 223 #
I do love travelling by train. A big part of the reason for this is the freedom it gives me to do other things while I'm travelling. Cars and busses simply can't offer that same empowerment. But even then travelling by train isn't the same as sitting at a desk that's static relative to the motion of the surface of the earth. Debugging multiple phones simultaneously just isn't very convenient on a train.

And so now here I am, back home at my desk, and able to properly perform the debugging I attempted to do yesterday while hurtling between Birmingham and Cambridge at 120 km per hour. It also helps that I'm not feeling quite so exhausted this morning after a long day either.

The question I'm asking is, when using the browser, which of the routes I identified yesterday are followed when creating the GLContext object, since this is where the offscreen status is set and stored.

Using the debugger it's easy to find where this is happening on ESR 78:
Thread 39 "Compositor" hit Breakpoint 1, mozilla::gl::GLContext::
    GLContext (this=this@entry=0x7ea01118b0, flags=mozilla::gl::
    CreateContextFlags::NONE, 
    caps=..., sharedContext=sharedContext@entry=0x0, isOffscreen=false, 
    useTLSIsCurrent=useTLSIsCurrent@entry=false)
    at gfx/gl/GLContext.cpp:274
274     GLContext::GLContext(CreateContextFlags flags, const SurfaceCaps& caps,
(gdb) bt
#0  mozilla::gl::GLContext::GLContext (this=this@entry=0x7ea01118b0, 
    flags=mozilla::gl::CreateContextFlags::NONE, caps=..., 
    sharedContext=sharedContext@entry=0x0, isOffscreen=false, 
    useTLSIsCurrent=useTLSIsCurrent@entry=false)
    at gfx/gl/GLContext.cpp:274
#1  0x0000007fba607af0 in mozilla::gl::GLContextEGL::GLContextEGL (
    this=0x7ea01118b0, egl=0x7ea0110db0, flags=<optimized out>, caps=..., 
    isOffscreen=<optimized out>, config=0x0, surface=0x5555cc3980, 
    context=0x7ea0004d80)
    at gfx/gl/GLContextProviderEGL.cpp:472
#2  0x0000007fba60f0d8 in mozilla::gl::GLContextProviderEGL::
    CreateWrappingExisting (aContext=0x7ea0004d80, aSurface=0x5555cc3980, 
    aDisplay=<optimized out>)
    at /home/flypig/Documents/Development/jolla/gecko-dev-project/gecko-dev/
    obj-build-mer-qt-xr/dist/include/mozilla/cxxalloc.h:33
#3  0x0000007fbca9a388 in mozilla::embedlite::nsWindow::GetGLContext (
    this=0x7f80945810)
    at mobile/sailfishos/embedshared/nsWindow.cpp:415
#4  0x0000007fba682718 in mozilla::layers::CompositorOGL::CreateContext (
    this=0x7ea0003420)
    at gfx/layers/opengl/CompositorOGL.cpp:228
#5  0x0000007fba6a33a4 in mozilla::layers::CompositorOGL::Initialize (
    this=0x7ea0003420, out_failureReason=0x7edb32d720)
    at gfx/layers/opengl/CompositorOGL.cpp:374
#6  0x0000007fba77aff4 in mozilla::layers::CompositorBridgeParent::
    NewCompositor (this=this@entry=0x7f808cbf80, aBackendHints=...)
    at gfx/layers/ipc/CompositorBridgeParent.cpp:1534
#7  0x0000007fba784660 in mozilla::layers::CompositorBridgeParent::
    InitializeLayerManager (this=this@entry=0x7f808cbf80, aBackendHints=...)
    at gfx/layers/ipc/CompositorBridgeParent.cpp:1491
#8  0x0000007fba7847a8 in mozilla::layers::CompositorBridgeParent::
    AllocPLayerTransactionParent (this=this@entry=0x7f808cbf80, 
    aBackendHints=..., aId=...)
    at gfx/layers/ipc/CompositorBridgeParent.cpp:1587
#9  0x0000007fbca81234 in mozilla::embedlite::EmbedLiteCompositorBridgeParent::
    AllocPLayerTransactionParent (this=0x7f808cbf80, aBackendHints=..., 
    aId=...)
    at mobile/sailfishos/embedthread/EmbedLiteCompositorBridgeParent.cpp:77
#10 0x0000007fba05f3f0 in mozilla::layers::PCompositorBridgeParent::
    OnMessageReceived (this=0x7f808cbf80, msg__=...) at 
    PCompositorBridgeParent.cpp:1391
[...]
#26 0x0000007fb735989c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/
    clone.S:78
(gdb) 
So this is the case of a call to CreateWrappingExisting():
already_AddRefed<GLContext> GLContextProviderEGL::CreateWrappingExisting(
    void* aContext, void* aSurface, void* aDisplay) {
[...]
  RefPtr<GLContextEGL> gl =
      new GLContextEGL(egl, CreateContextFlags::NONE, caps, false, config,
                       (EGLSurface)aSurface, (EGLContext)aContext);
[...]
On ESR 91 the situation is that we have a call to GLContextEGL::CreateEGLPBufferOffscreenContextImpl():
Thread 37 &quot;Compositor&quot; hit Breakpoint 1, mozilla::gl::GLContext::
    GLContext (this=this@entry=0x7f6019aa80, desc=..., 
    sharedContext=sharedContext@entry=0x0, 
    useTLSIsCurrent=useTLSIsCurrent@entry=false)
    at gfx/gl/GLContext.cpp:283
283     GLContext::GLContext(const GLContextDesc& desc, GLContext* 
    sharedContext,
(gdb) bt
#0  mozilla::gl::GLContext::GLContext (this=this@entry=0x7f6019aa80, desc=..., 
    sharedContext=sharedContext@entry=0x0, 
    useTLSIsCurrent=useTLSIsCurrent@entry=false)
    at gfx/gl/GLContext.cpp:283
#1  0x0000007ff28a9450 in mozilla::gl::GLContextEGL::GLContextEGL (
    this=0x7f6019aa80, 
    egl=std::shared_ptr<mozilla::gl::EglDisplay> (use count 5, weak count 2) = 
    {...}, desc=..., config=0x5555ab3f60, surface=0x7f60004bb0, 
    context=0x7f60004c30)
    at gfx/gl/GLContextProviderEGL.cpp:496
#2  0x0000007ff28cfd18 in mozilla::gl::GLContextEGL::CreateGLContext (egl=std::
    shared_ptr<mozilla::gl::EglDisplay> (use count 5, weak count 2) = {...}, 
    desc=..., config=<optimized out>, config@entry=0x5555ab3f60, 
    surface=surface@entry=0x7f60004bb0, useGles=useGles@entry=true, 
    out_failureId=out_failureId@entry=0x7fb179c1b8)
    at ${PROJECT}/obj-build-mer-qt-xr/dist/include/mozilla/cxxalloc.h:33
#3  0x0000007ff28d0858 in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContextImpl (
    egl=std::shared_ptr<mozilla::gl::EglDisplay> (use count 5, weak count 2) = 
    {...}, desc=..., size=..., useGles=useGles@entry=true, 
    out_failureId=out_failureId@entry=0x7fb179c1b8)
    at include/c++/8.3.0/ext/atomicity.h:96
#4  0x0000007ff28d0a6c in mozilla::gl::GLContextEGL::
    CreateEGLPBufferOffscreenContext (
    display=std::shared_ptr<mozilla::gl::EglDisplay> (use count 5, weak count 
    2) = {...}, desc=..., size=..., 
    out_failureId=out_failureId@entry=0x7fb179c1b8)
    at include/c++/8.3.0/ext/atomicity.h:96
#5  0x0000007ff28d0ba0 in mozilla::gl::GLContextProviderEGL::CreateHeadless (
    desc=..., out_failureId=out_failureId@entry=0x7fb179c1b8)
    at include/c++/8.3.0/ext/atomicity.h:96
#6  0x0000007ff293abc0 in mozilla::layers::CompositorOGL::CreateContext (
    this=this@entry=0x7f60002ed0)
    at gfx/layers/opengl/CompositorOGL.cpp:254
#7  0x0000007ff29503b8 in mozilla::layers::CompositorOGL::Initialize (
    this=0x7f60002ed0, out_failureReason=0x7fb179c510)
    at gfx/layers/opengl/CompositorOGL.cpp:397
#8  0x0000007ff2a66094 in mozilla::layers::CompositorBridgeParent::
    NewCompositor (this=this@entry=0x7fc89abd50, aBackendHints=...)
    at gfx/layers/ipc/CompositorBridgeParent.cpp:1493
#9  0x0000007ff2a71110 in mozilla::layers::CompositorBridgeParent::
    InitializeLayerManager (this=this@entry=0x7fc89abd50, aBackendHints=...)
    at gfx/layers/ipc/CompositorBridgeParent.cpp:1436
#10 0x0000007ff2a71240 in mozilla::layers::CompositorBridgeParent::
    AllocPLayerTransactionParent (this=this@entry=0x7fc89abd50, 
    aBackendHints=..., aId=...)
    at gfx/layers/ipc/CompositorBridgeParent.cpp:1546
#11 0x0000007ff4e07ca8 in mozilla::embedlite::EmbedLiteCompositorBridgeParent::
    AllocPLayerTransactionParent (this=0x7fc89abd50, aBackendHints=..., 
    aId=...)
    at mobile/sailfishos/embedthread/EmbedLiteCompositorBridgeParent.cpp:80
#12 0x0000007ff23fe52c in mozilla::layers::PCompositorBridgeParent::
    OnMessageReceived (this=0x7fc89abd50, msg__=...) at 
    PCompositorBridgeParent.cpp:1285
[...]
#27 0x0000007fefba889c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/
    clone.S:78
(gdb) 
These differences are bigger than expected; I'll need to realign them.

Both backtraces have CompositorOGL::CreateContext() in them at frame 4 and 6 respectively, so that's presumably where the decision to go one way or the other is happening. In the ESR 78 executable nsWindow::GetGLContext() is being called from there, whilst in ESR 91 it's GLContextProviderEGL::CreateHeadless().

So the difference here appears to be that on ESR 91 the following condition is entered:
  // Allow to create offscreen GL context for main Layer Manager
  if (!context && gfxEnv::LayersPreferOffscreen()) {
[...]
On ESR 78 it's never reached. The reason becomes clear as I step through the code. The value of the widgetOpenGLContext variable that's collected from the widget is non-null, causing the method to exit early:
Thread 39 &quot;Compositor&quot; hit Breakpoint 1, mozilla::layers::
    CompositorOGL::CreateContext (this=0x7ea0003420)
    at gfx/layers/opengl/CompositorOGL.cpp:223
223     already_AddRefed<mozilla::gl::GLContext> CompositorOGL::CreateContext() 
    {
(gdb) n
227       nsIWidget* widget = mWidget->RealWidget();
(gdb) p context
$1 = {mRawPtr = 0x0}
(gdb) n
228       void* widgetOpenGLContext =
(gdb) p widget
$2 = (nsIWidget *) 0x7f80c86f60
(gdb) n
230       if (widgetOpenGLContext) {
(gdb) p widgetOpenGLContext
$3 = (void *) 0x7ea0111800
(gdb) 
As on ESR 78, on ESR 91 the value of context is set to null, while widget has a non-null value. But unlike on ESR 78 the widgetOpenGLContext that's retrieved from widget is null:
Thread 37 &quot;Compositor&quot; hit Breakpoint 1, mozilla::layers::
    CompositorOGL::CreateContext (this=this@entry=0x7ed8002ed0)
    at gfx/layers/opengl/CompositorOGL.cpp:227
227     already_AddRefed<mozilla::gl::GLContext> CompositorOGL::CreateContext() 
    {
(gdb) n
231       nsIWidget* widget = mWidget->RealWidget();
(gdb) p context
$3 = {mRawPtr = 0x0}
(gdb) n
232       void* widgetOpenGLContext =
(gdb) p widget
$4 = (nsIWidget *) 0x7fc8550d80
(gdb) n
234       if (widgetOpenGLContext) {
(gdb) p widgetOpenGLContext
$5 = (void *) 0x0
(gdb) 
As a consequence of this the method doesn't return early and the context is created via a different route as a result. So the question we have to answer is why the following is returning a value on ESR 78 but returning null on ESR 91:
  void* widgetOpenGLContext =
      widget ? widget->GetNativeData(NS_NATIVE_OPENGL_CONTEXT) : nullptr;
Finding out the answer to this will have to wait until tomorrow, when I have a bit more time in which I'll hopefully be able to get this sorted.

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