flypig.co.uk

List items

Items from the current list are shown below.

Blog

12 Mar 2024 : Day 183 #
Before we get in to my usual dev diary I want to fist draw attention to a couple of new development blogs that have started up recently. Both related to mobile operating system development and Linux in particular.

First up is Adventures with Sailfish and Ofono from Adam Pigg (piggz). Adam will be well-known to many amSailfish OS users and already featured here back on Day 178.

A long-time porter of Sailfish OS, Adam is responsible for the native PinePhone, PinePhone Pro and Volla ports, amongst others.

He's recently turned his hand to contributing Sailfish-specific Ofono changes to upstream, with the aim of reversing the divergence that's grown between the two over the years. If successful, this would not only add functionality to upstream Ofono, it would also allow updating the Sailfish OS version and benefiting from recent upstream improvements as well.

Adam recently started writing a semi-daily blog about it. He's up to Day 5 already and it's a great read.

But it's not just Adam. Peter Mack (1peter10) from LINMOB.net has started a developer diary to chart his explorations of — and improvements to — Mobile Config Firefox. The project is aimed at getting Firefox nicely configured for mobile use, part of the postmarketOS project. Peter has already written about his first pull request to tidy up the URL bar for use on smaller displays.

I'm really enjoying reading about others' approach to development and watching as things progress. I'll be following along avidly to both.

It might seem a little obvious, but I also recommend Peter's weekly Mobile Linux Update as the best way to catch up on all the latest activity in the mobile Linux space. I like to think I'm keeping up with developments in the world of Sailfish OS, but keeping up with activity across all of the various distributions is a real challenge. I'd say it was impossible, except that this is exactly what Peter does, making it possible for the rest of us to keep up in the process.

On a separate but related note, I also want to give a shout-out to Florian Xaver (wosrediinanatour). Florian has been extremely helpful reviewing some of the code changes mentioned here in my diary. He's been sharing useful advice and tips. I'm going to go into this in more detail in a future diary entry, but for now, let me just say that I'm grateful for the input.

Alright, let's move back on to the gecko development track. After taking some steps to align the ESR 78 and ESR 91 offscreen rendering pipeline yesterday, I'm following on with more of the same today. My plan is to step through various methods I know to be relevant as part of the render process and see whether they differ between ESR 78 and ESR 91. I have a pretty good setup for this. Two phones, one with ESR 78 another with ESR 91. Two SSH sessions, one for each phone, running my test application through the debugger. Then on another display I have Qt Creator running with ESR 78 code on one side and ESR 91 code on the other.
 
My desktop arrangement: laptop, two phones and a screen; plus some mess

With this setup I can step through the code simultaneously on ESR 78 and ESR 91 to establish whether they diverge or not, and if so where. The first method I'm going to look at is the same one we started with yesterday, which is GLScreenBuffer::Swap(). What I'd really like to do is show the debugger output side-by-side here, but the line lengths are too wide for it to comfortably fit, so I'm just going to have to list them here serially.

Working this way it doesn't take long before I'm able to identify a critical issue. First ESR 78.
(gdb) b GLScreenBuffer::Swap
Breakpoint 2 at 0x7fb8e672b8: file dist/include/mozilla/UniquePtr.h, line 287.
(gdb) c
Continuing.

Thread 36 "Compositor" hit Breakpoint 2, mozilla::gl::GLScreenBuffer::Swap
    (this=this@entry=0x7eac003c00, size=...)
    at dist/include/mozilla/UniquePtr.h:287
287     in dist/include/mozilla/UniquePtr.h
(gdb) p size
$1 = (const mozilla::gfx::IntSize &) @0x7eac1deaa8:
    {<mozilla::gfx::BaseSize<int, mozilla::gfx::IntSizeTyped<mozilla::gfx::
    UnknownUnits> >> = {{{width = 1080, height = 2520}, components =
    {1080, 2520}}}, <mozilla::gfx::UnknownUnits> = {<No data fields>},
    <No data fields>}
(gdb) n
382       if (!newBack) return false;
(gdb) p newBack
$2 = {mRawPtr = 0x7eac138860}
(gdb) 
And now ESR 91.
(gdb) break GLScreenBuffer::Swap
Breakpoint 2 at 0x7ff1106f8c: file ${PROJECT}/gfx/gl/GLScreenBuffer.cpp, line 506.
(gdb) c
Continuing.
[LWP 22652 exited]

Thread 36 "Compositor" hit Breakpoint 2, mozilla::gl::GLScreenBuffer::Swap
    (this=this@entry=0x5555642d50, size=...)
    at ${PROJECT}/gfx/gl/GLScreenBuffer.cpp:506
506     in ${PROJECT}/gfx/gl/GLScreenBuffer.cpp
(gdb) p size
$1 = (const mozilla::gfx::IntSize &) @0x7edc1a21e4:
    {<mozilla::gfx::BaseSize<int, mozilla::gfx::IntSizeTyped<mozilla::gfx::
    UnknownUnits> >> = {{{width = 1080, height = 2520}, components =
    {1080, 2520}}}, <mozilla::gfx::UnknownUnits> = {<No data fields>},
    <No data fields>}
(gdb) n
[LWP 22657 exited]
290     ${PROJECT}/obj-build-mer-qt-xr/dist/include/mozilla/UniquePtr.h:
    No such file or directory.
(gdb) n
509     ${PROJECT}/gfx/gl/GLScreenBuffer.cpp: No such file or directory.
(gdb) p newBack
$2 = {mRawPtr = 0x0}
(gdb) 
Debugging on the ESR 91 build isn't so clean due to the partial build messing up some of the debug source alignment, but we can nevertheless see that the call to SurfaceFactory_EGLImage::NewTexClient() is returning something sensible in ESR 78, but null in ESR 91. Here's the relevant code:
  RefPtr<layers::SharedSurfaceTextureClient> newBack =
      mFactory->NewTexClient(size);
  if (!newBack) return false;
Let's ensure that mFactory is valid and of the correct type. First on ESR 78:
(gdb) p mFactory.mTuple.mFirstA
$4 = (mozilla::gl::SurfaceFactory *) 0x7eac139b60
(gdb) set print object on
(gdb) p mFactory.mTuple.mFirstA
$5 = (mozilla::gl::SurfaceFactory_EGLImage *) 0x7eac139b60
(gdb) set print object off
(gdb) 
And then, to compare, on ESR 91
(gdb) p mFactory.mTuple.mFirstA
$7 = (mozilla::gl::SurfaceFactory *) 0x7edc1dc470
(gdb) set print object on
(gdb) p mFactory.mTuple.mFirstA
$8 = (mozilla::gl::SurfaceFactory_EGLImage *) 0x7edc1dc470
(gdb) set print object off
(gdb) 
That all looks similar, so the next thing to check is what's happening inside SurfaceFactory_EGLImage::NewTexClient() that's preventing it from doing what it's supposed to. But when I try to place a breakpoint on SurfaceFactory_EGLImage::NewTexClient() I discover I can't: it doesn't exist.

The SurfaceFactory_EGLImage class must be inheriting the method from SurfaceFactory::NewTexClient(). So we can check by stepping through that. First the ESR 78 code.
(gdb) b SurfaceFactory::NewTexClient
Breakpoint 3 at 0x7fb8e6f338: file gfx/gl/SharedSurface.cpp, line 287.
(gdb) c
Continuing.

Thread 36 "Compositor" hit Breakpoint 3, mozilla::gl::SurfaceFactory::
    NewTexClient (this=0x7eac139b60, size=...)
    at gfx/gl/SharedSurface.cpp:287
287     SurfaceFactory::NewTexClient(const gfx::IntSize& size) {
(gdb) bt
#0  mozilla::gl::SurfaceFactory::NewTexClient (this=0x7eac139b60, size=...)
    at gfx/gl/SharedSurface.cpp:287
#1  0x0000007fb8e672d8 in mozilla::gl::GLScreenBuffer::Swap
    (this=this@entry=0x7eac003c00, size=...)
    at dist/include/mozilla/UniquePtr.h:287
[...]
#25 0x0000007fbe70d89c in ?? () from /lib64/libc.so.6
(gdb) p size
$6 = (const mozilla::gfx::IntSize &) @0x7eac140ec8:
    {<mozilla::gfx::BaseSize<int, mozilla::gfx::IntSizeTyped<mozilla::gfx::
    UnknownUnits> >> = {{{width = 1080, height = 2520}, components =
    {1080, 2520}}}, <mozilla::gfx::UnknownUnits> = {<No data fields>},
    <No data fields>}
(gdb) p mRecycleFreePool
$7 = {mQueue = std::queue wrapping: std::deque with 0 elements}
(gdb) n
1367    include/c++/8.3.0/bits/stl_deque.h: No such file or directory.
(gdb) n
300       UniquePtr<SharedSurface> surf = CreateShared(size);
(gdb) n
301       if (!surf) return nullptr;
(gdb) p surf.mTuple.mFirstA
$8 = (mozilla::gl::SharedSurface *) 0x7eac1802b0
(gdb) n
292     dist/include/mozilla/UniquePtr.h: No such file or directory.
(gdb) n
289     dist/include/mozilla/RefPtr.h: No such file or directory.
(gdb) n
305                                                        mAllocator, mFlags);
(gdb) n
307       StartRecycling(ret);
(gdb) p ret
$10 = {mRawPtr = 0x7eac138910}
(gdb) p mAllocator
$11 = {mRawPtr = 0x0}
(gdb) p mFlags
$12 = mozilla::layers::TextureFlags::ORIGIN_BOTTOM_LEFT
(gdb) 
Notice how the call to CreateShared() returns an object which then when moved into Create() returns another object. The allocator is null and the flags are set to ORIGIN_BOTTOM_LEFT.

On ESR 91 there's a big difference: although mAllocator and mFlags are set correctly, the call to CreateShared returns null. Immediately afterwards the method notices this and returns early.
(gdb) b SurfaceFactory::NewTexClient
Breakpoint 3 at 0x7ff111d888: file ${PROJECT}/gfx/gl/SharedSurface.cpp, line 393.
(gdb) c
Continuing.

Thread 36 "Compositor" hit Breakpoint 3, mozilla::gl::SurfaceFactory::
    NewTexClient (this=0x7edc1dc470, size=...)
    at ${PROJECT}/gfx/gl/SharedSurface.cpp:393
393     ${PROJECT}/gfx/gl/SharedSurface.cpp: No such file or directory.
(gdb) bt
#0  mozilla::gl::SurfaceFactory::NewTexClient (this=0x7edc1dc470, size=...)
    at ${PROJECT}/gfx/gl/SharedSurface.cpp:393
#1  0x0000007ff1106fac in mozilla::gl::GLScreenBuffer::Swap
    (this=this@entry=0x5555642d50, size=...)
    at ${PROJECT}/obj-build-mer-qt-xr/dist/include/mozilla/UniquePtr.h:290
[...]
#24 0x0000007ff6a0489c in ?? () from /lib64/libc.so.6
(gdb) p size
$17 = (const mozilla::gfx::IntSize &) @0x7ed81a22e4:
    {<mozilla::gfx::BaseSize<int, mozilla::gfx::IntSizeTyped<mozilla::gfx::
    UnknownUnits> >> = {{{width = 1080, height = 2520}, components =
    {1080, 2520}}}, <mozilla::gfx::UnknownUnits> = {<No data fields>},
    <No data fields>}
(gdb) p mRecycleFreePool
$18 = {mQueue = std::queue wrapping: std::deque with 0 elements}
(gdb) p mAllocator
$19 = {mRawPtr = 0x0}
(gdb) p mFlags
$20 = mozilla::layers::TextureFlags::ORIGIN_BOTTOM_LEFT
(gdb) p mRecycleFreePool
$21 = {mQueue = std::queue wrapping: std::deque with 0 elements}
(gdb) n
394     in ${PROJECT}/gfx/gl/SharedSurface.cpp
(gdb) n
406     in ${PROJECT}/gfx/gl/SharedSurface.cpp
(gdb) n
407     in ${PROJECT}/gfx/gl/SharedSurface.cpp
(gdb) p surf.mTuple.mFirstA
$22 = (mozilla::gl::SharedSurface *) 0x0
(gdb) n
79      ${PROJECT}/obj-build-mer-qt-xr/dist/include/mozilla/RefPtr.h:
    No such file or directory.
(gdb) n
mozilla::gl::GLScreenBuffer::Swap (this=this@entry=0x5555643a10, size=...)
    at ${PROJECT}/gfx/gl/GLScreenBuffer.cpp:509
509     ${PROJECT}/gfx/gl/GLScreenBuffer.cpp: No such file or directory.
(gdb) 
So it would seem that there's a problem in CreateShared(), so the next step will be to drill down into that. That's all I've time for today though; we'll pick this up again 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