flypig.co.uk

List items

Items from the current list are shown below.

Blog

28 Oct 2023 : Day 73 #
Yesterday I was, after much wrangling, finally able to get the render to be active when painting occurs. There's still no actual rendering taking place to the screen so this isn't enough to get things working, but it's an essential step forwards.

Today I'm looking into the nsDisplayBorder::Paint() method, which is now getting successfully called, to find out if there's anything lower down the stack that may be preventing the actual render instructions from being enacted.

I ran the ESR 78 build first and got the following call stack for nsDisplayBorder::Paint().
Thread 10 "GeckoWorkerThre" hit Breakpoint 4, nsDisplayBorder::Paint
    (this=0x7fb82968c0, aBuilder=0x7fde8d4630, aCtx=0x7fb8e352a0)
    at /usr/src/debug/xulrunner-qt5-78.15.1+git33.2-1.21.1.jolla.aarch64/layout/
    painting/nsDisplayList.cpp:5031
5031	void nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
(gdb) bt
#0  nsDisplayBorder::Paint (this=0x7fb82968c0, aBuilder=0x7fde8d4630,
    aCtx=0x7fb8e352a0)
    at /usr/src/debug/xulrunner-qt5-78.15.1+git33.2-1.21.1.jolla.aarch64/layout/
    painting/nsDisplayList.cpp:5031
#1  0x0000007ff44e9bdc in mozilla::FrameLayerBuilder::PaintItems
    (this=this@entry=0x7fb8df2cc0, aItems=std::vector of length 60, capacity
    118 = {...}, aRect=..., aContext=aContext@entry=0x7fb8e352a0,
    aBuilder=aBuilder@entry=0x7fde8d4630, aPresContext=aPresContext@entry=
    0x7fb90afd30, aOffset=..., aXScale=<optimized out>, aYScale=<optimized out>)
    at /usr/src/debug/xulrunner-qt5-78.15.1+git33.2-1.21.1.jolla.aarch64/layout/
    painting/FrameLayerBuilder.cpp:7093
[...]
#46 0x0000007fef65b89c in ?? () from /lib64/libc.so.6
(gdb) 
I then ran the same command with the same breakpoints using the new ESR 91 executable. Here's what I got:
Thread 8 "GeckoWorkerThre" hit Breakpoint 5, nsDisplayBorder::Paint
    (this=0x7f88f05aa8, aBuilder=0x7f9f3d1268, aCtx=0x7f88db8e70)
    at /usr/src/debug/xulrunner-qt5-91.9.1-1.aarch64/layout/
    painting/nsDisplayList.cpp:5138
5138	void nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
(gdb) bt
#0  nsDisplayBorder::Paint (this=0x7f88f05aa8, aBuilder=0x7f9f3d1268,
    aCtx=0x7f88db8e70)
    at /usr/src/debug/xulrunner-qt5-91.9.1-1.aarch64/layout/
    painting/nsDisplayList.cpp:5138
#1  0x0000007fbc3a5584 in mozilla::FrameLayerBuilder::PaintItems
    (this=this@entry=0x7ef0005c10, aItems=std::vector of length 60, capacity
    64 = {...}, aRect=..., aContext=aContext@entry=0x7f88db8e70,
    aBuilder=aBuilder@entry=0x7f9f3d1268, aPresContext=aPresContext@entry=
    0x7f88b6d270, aOffset=..., aXScale=1, aYScale=<optimized out>)
    at /usr/src/debug/xulrunner-qt5-91.9.1-1.aarch64/layout/
    painting/FrameLayerBuilder.cpp:7112
[...]
#49 0x0000007fb78b389c in ?? () from /lib64/libc.so.6
(gdb) 
So they both look very similar and they're both being correctly called. There's not much else to be gained from these backtraces, except that it gives us a platform to work from. The question now is: what happens inside these methods and inside the methods they call.

Manually digging down into the code, I've read all the way down to nsCSSRendering::PaintBorderWithStyleBorder() but not yet quite as far as nsImageRenderer::Draw(). I'm definitely getting closer to the GLES or other commands that actually perform the rendering.

Let's look in more detail at this nsCSSBorderRenderer::DrawBorders() method. Inside the drawing calls are all methods that belong to the mDrawTarget instance of the class on ESR 78. We can see from the code that this is a pointer to an instance of type DrawTarget. What's harder to tell is whether it's actually this, or some other class that inherits from DrawTarget.

Stepping through the code allows us to check this.
(gdb) explore mDrawTarget
'mDrawTarget' is a pointer to a value of type 'nsCSSBorderRenderer::DrawTarget'
Continue exploring it as a pointer to a single value [y/n]: y

The value of '*mDrawTarget' is of type 'nsCSSBorderRenderer::DrawTarget' which
    is a typedef of type 'mozilla::gfx::DrawTarget'
The value of '*mDrawTarget' is a struct/class of type 'mozilla::gfx::DrawTarget'
    with the following fields:

  mozilla::external::AtomicRefCounted<mozilla::gfx::DrawTarget>
                  = <Enter 0 to explore this base class of type
                    'mozilla::external::AtomicRefCounted<mozilla::gfx::DrawTarget>'>
        mUserData = <Enter 1 to explore this field of type 'mozilla::gfx::UserData'>
       mTransform = <Enter 2 to explore this field of type 'mozilla::gfx::Matrix'>
      mOpaqueRect = <Enter 3 to explore this field of type 'mozilla::gfx::IntRect'>
  mTransformDirty = true .. (Value of type 'bool')
mPermitSubpixelAA = true .. (Value of type 'bool')
          mFormat = mozilla::gfx::SurfaceFormat::B8G8R8X8 ..
                    (Value of type 'mozilla::gfx::SurfaceFormat')

Enter the field number of choice: 
(gdb) 
This is useful. It tells us that the actual class is of type nsCSSBorderRenderer::DrawTarget. It's possible this will be overriding some methods, so we should look at this class carefully. Moreover, it's good to see that this mDrawTarget exists in very similar ways for both builds.

As a result of looking through all this code I'm fairly confident now that the rendering is happening to the render target and that it's the render target itself that's the problem, either because it's not capturing the result or (which I think is the more likely) the render target simply isn't making it on to the screen.

But this rendering is happening at the sharp end. If I need to consider the render target I'll need to move right out from the micro to the macro and consider what's happening elsewhere in the rendering pipeline.

What this means, as has generally been the case so far, is that I've made progress, eliminated one line of enquiry, and given me more focus on where the problem is hiding. And also a whole bunch of new things to check.

We'll get there.

For all the other entries in my developer diary, check out the Gecko-dev Diary page.

Comments

Uncover Disqus comments