List items
Items from the current list are shown below.
Blog
2 Nov 2023 : Day 78 #
So, I'm back today looking now at the other end of the rendering pipeline. At the end of the day working on this yesterday I concluded I needed to do two tasks:
Putting a breakpoint on both versions works: both are triggered from nsWindow::GetGLContext() with the aDisplay set to 0x1 as expected. From this point on the actual internals of the two respective methods differ quite considerably.
The ESR 78 code passes the display to a call to GLLibraryEGL::EnsureInitialized(false, &discardFailureId, aDisplay). It then creates a GLContextEGL which it configures and returns.
The ESR 91 code gets the DefaultEglLibrary and uses it to create an EglDisplay structure, which involves passing in the aDisplay value: EglDisplay::Create(*lib.operator->(), (EGLContext)aDisplay, false). It finishes up creating a new GLContextEGL instance similar to the way ESR 78 does.
The initial step through of both each version throws up nothing unusual. For ESR 78:
One obvious difference is how GLLibraryEGL::CreateDisplay() is called. In ESR 78 this happens inside the call to GLLibraryEGL::DoEnsureInitialized(). In ESR 91 this method has been renamed to GLLibraryEGL::Init() and is quite similar, apart from the fact that there is no call to GLLibraryEGL::CreateDisplay() inside it. It's notably absent.
The question I'm therefore wondering is: where, if at all, does this get called in ESR 91. I'm going to find out.
Here it is in ESR 78:
From the code it's possible to see how this has happened. I've even discussed it in previous posts. Essentially there was a change that meant all of the displays are created internally, rather than allowing them to be passed in externally. This is a problem for us because when it comes to the Sailfish Browser the display is created in qtmozembed and passed in from there.
In ESR 78 this display gets passed in to GLLibraryEGL::DoEnsureInitialized() (you can see it in the backtrace just earlier). Towards the end of this method there's a call like this:
In ESR 91 this all changed. Here things would have happened via the GLContextEGLFactory::CreateImpl() method, but this removed the ability to pass in a display.
In the code now, the EglDisplay still goes into a "create" method like this:
This has all become rather confusing and the different methods are swimming around in my head. I'm fairly certain that means I've reached the limit of my ability to work on this tonight. I'll have to pick it up again tomorrow.
For all the other entries in my developer diary, check out the Gecko-dev Diary page.
- Step through GLContextProviderEGL::CreateWrappingExisting() and the changes made in commit 51e18eb9b16ee94a.
- Check the unapplied patches to check whether there anything crucial missing.
Putting a breakpoint on both versions works: both are triggered from nsWindow::GetGLContext() with the aDisplay set to 0x1 as expected. From this point on the actual internals of the two respective methods differ quite considerably.
The ESR 78 code passes the display to a call to GLLibraryEGL::EnsureInitialized(false, &discardFailureId, aDisplay). It then creates a GLContextEGL which it configures and returns.
The ESR 91 code gets the DefaultEglLibrary and uses it to create an EglDisplay structure, which involves passing in the aDisplay value: EglDisplay::Create(*lib.operator->(), (EGLContext)aDisplay, false). It finishes up creating a new GLContextEGL instance similar to the way ESR 78 does.
The initial step through of both each version throws up nothing unusual. For ESR 78:
1098 if (!GLLibraryEGL::EnsureInitialized (false, &discardFailureId, aDisplay)) { (gdb) n 1103 if (!aContext || !aSurface) return nullptr; (gdb) n 1105 const auto& egl = GLLibraryEGL::Get(); (gdb) n 1106 SurfaceCaps caps = SurfaceCaps::Any(); (gdb) n 1110 (EGLSurface)aSurface, (EGLContext)aContext); (gdb) n 1106 SurfaceCaps caps = SurfaceCaps::Any(); (gdb) n 1112 gl->mOwnsContext = false; (gdb) n 1106 SurfaceCaps caps = SurfaceCaps::Any(); (gdb) n 1097 nsCString discardFailureId; (gdb) n mozilla::embedlite::nsWindow::GetGLContext (this=0x7fb8ce4970) at mobile/ sailfishos/embedshared/nsWindow.cpp:416 416 if (!mozContext || !mozContext->Init()) {And for ESR 91:
(gdb) n 1000 if (!aContext || !aSurface) return nullptr; (gdb) n 1002 nsCString failureId; (gdb) n 1003 const auto lib = gl::DefaultEglLibrary(&failureId); (gdb) n 1004 if (!lib) { (gdb) n 1008 const auto egl = EglDisplay::Create(*lib.operator->(), (EGLContext)aDisplay, false); (gdb) n 1009 if (!egl) { (gdb) n 1016 const auto desc = GLContextDesc{{flags}, false}; (gdb) n 1021 (EGLSurface)aSurface, (EGLContext)aContext); (gdb) n 1022 gl->SetIsDoubleBuffered(true); (gdb) n 1023 gl->mOwnsContext = false; (gdb) n 1008 const auto egl = EglDisplay::Create(*lib.operator->(), (EGLContext)aDisplay, false); (gdb) n 1003 const auto lib = gl::DefaultEglLibrary(&failureId); (gdb) n 1002 nsCString failureId; (gdb) n mozilla::embedlite::nsWindow::GetGLContext (this=this@entry=0x7f88580b50) at mobile/ sailfishos/embedshared/nsWindow.cpp:421 421 if (!mozContext || !mozContext->Init()) {They both bounce around a bit, but none of them drop out early due to failures or null pointers.
One obvious difference is how GLLibraryEGL::CreateDisplay() is called. In ESR 78 this happens inside the call to GLLibraryEGL::DoEnsureInitialized(). In ESR 91 this method has been renamed to GLLibraryEGL::Init() and is quite similar, apart from the fact that there is no call to GLLibraryEGL::CreateDisplay() inside it. It's notably absent.
The question I'm therefore wondering is: where, if at all, does this get called in ESR 91. I'm going to find out.
Here it is in ESR 78:
Thread 38 "Compositor" hit Breakpoint 2, mozilla::gl::GLLibraryEGL::CreateDisplay (this=this@entry=0x7ed81a25f0, forceAccel=forceAccel@entry=false, gfxInfo=..., out_failureId=out_failureId@entry=0x7f2200e298, aDisplay=aDisplay@entry=0x1) at gfx/gl/GLLibraryEGL.cpp:760 760 EGLDisplay aDisplay) { (gdb) bt #0 mozilla::gl::GLLibraryEGL::CreateDisplay (this=this@entry=0x7ed81a25f0, forceAccel=forceAccel@entry=false, gfxInfo=..., out_failureId=out_failureId@entry=0x7f2200e298, aDisplay=aDisplay@entry=0x1) at gfx/gl/GLLibraryEGL.cpp:760 #1 0x0000007ff29106c4 in mozilla::gl::GLLibraryEGL::DoEnsureInitialized (this=0x7ed81a25f0, forceAccel=false, out_failureId=0x7f2200e298, aDisplay=0x1) at gfx/gl/GLLibraryEGL.cpp:578 #2 0x0000007ff2910e3c in mozilla::gl::GLLibraryEGL::DoEnsureInitialized (this=<optimized out>, forceAccel=<optimized out>, out_failureId=<optimized out>, aDisplay=<optimized out>) at gfx/gl/GLLibraryEGL.cpp:403 #3 0x0000007ff2911028 in mozilla::gl::GLContextProviderEGL:: CreateWrappingExisting (aContext=0x7ed8004e70, aSurface=0x5555ba2d70, aDisplay=<optimized out>) at gfx/gl/GLContextProviderEGL.cpp:1098But in ESR 91 it's not getting called at all. This is a potentially important difference and definitely worth digging in to further.
From the code it's possible to see how this has happened. I've even discussed it in previous posts. Essentially there was a change that meant all of the displays are created internally, rather than allowing them to be passed in externally. This is a problem for us because when it comes to the Sailfish Browser the display is created in qtmozembed and passed in from there.
In ESR 78 this display gets passed in to GLLibraryEGL::DoEnsureInitialized() (you can see it in the backtrace just earlier). Towards the end of this method there's a call like this:
mEGLDisplay = CreateDisplay(forceAccel, gfxInfo, out_failureId, aDisplay); if (!mEGLDisplay) { return false; }If aDisplay isn't set then the CreateDisplay() method does some work. But if it is set — which is the case we're interested in — then the method just returns the value that was passed in without doing anything with it.
In ESR 91 this all changed. Here things would have happened via the GLContextEGLFactory::CreateImpl() method, but this removed the ability to pass in a display.
In the code now, the EglDisplay still goes into a "create" method like this:
Thread 34 "Compositor" hit Breakpoint 4, mozilla::gl::EglDisplay::EglDisplay (this=0x555596e700, lib=..., disp=0x1, isWarp=false) at gfx/gl/GLLibraryEGL.cpp:681 681 EglDisplay::EglDisplay(const PrivateUseOnly&, GLLibraryEGL& lib, (gdb) bt #0 mozilla::gl::EglDisplay::EglDisplay (this=0x555596e700, lib=..., disp=0x1, isWarp=false) at gfx/gl/GLLibraryEGL.cpp:681 #1 0x0000007fba5c4260 in __gnu_cxx::new_allocator<mozilla::gl::EglDisplay>:: construct<mozilla::gl::EglDisplay, mozilla::gl::EglDisplay::PrivateUseOnly, mozilla::gl::GLLibraryEGL&, void* const&, bool const&> (__p=0x555596e700, this=<optimized out>) at /srv/mer/toolings/SailfishOS-4.5.0.18/opt/cross/aarch64-meego-linux-gnu/ include/c++/8.3.0/new:169 [...] #9 mozilla::gl::EglDisplay::Create (lib=..., display=<optimized out>, display@entry=0x1, isWarp=isWarp@entry=false) at gfx/gl/GLLibraryEGL.cpp:676 #10 0x0000007fba5c4420 in mozilla::gl::GLContextProviderEGL:: CreateWrappingExisting (aContext=0x7eb80041a0, aSurface=0x55559676b0, aDisplay=0x1) at gfx/gl/GLContextProviderEGL.cpp:1008The call to the EglDisplay constructor is somewhat masked by this line:
const auto ret = std::make_sharedSo in ESR 78 we call GLLibraryEGL::CreateDisplay() whereas in ESR 91 we call EglDisplay::Create(). Both are defined in GLLibraryEGL.cpp, but they are from different classes and do different things. What we really want is for the ESR 91 to also call GLLibraryEGL::CreateDisplay(). That method exists, although it changed so that it can't take in display values. So that's what we're going to have to change I think.(PrivateUseOnly{}, lib, display, isWarp);
This has all become rather confusing and the different methods are swimming around in my head. I'm fairly certain that means I've reached the limit of my ability to work on this tonight. I'll have to pick it up again tomorrow.
For all the other entries in my developer diary, check out the Gecko-dev Diary page.
Comments
Uncover Disqus comments