List items
Items from the current list are shown below.
Blog
9 Apr 2024 : Day 211 #
I've been talking about wrapping up my investigation of offscreen rendering initialisation for several days now, so I really ought to pull my finger out and actually move on. It's just, as I look through the code, I keep on finding new things to check. All of them have provided a little more insight, but none of them have resulted in a working renderer.
Today I stumbled on a new thing to check. The code that swaps the buffer is an obvious area where things might be going wrong. And since there's not much of it and it all happens within the CompositorOGL::EndFrame() method in both versions (which, incidentally, share the same code almost identically) it seemed worth spending the time to check it.
So first up the actual code that swaps the buffers. The idea is that the previous rendered frame is held in one buffer; the next frame is rendered off screen and then swapped out for the old one. This ensures the swap happens fast, minimising the chance of artefacts and flicker appearing during the render cycle.
Here's a copy of the method for reference.
It's therefore an obvious concern that this might be causing problems for the offscreen render pipeline as well. Clearly on ESR 78 these are disabled, but are they on ESR 91? Here's what we get when we try with ESR 91:
While stepping through this I noticed that when stepping out of the SwapBuffers() method I end up in the CompositorOGL::EndFrame() method. This is also a pretty simple and linear method, so I figure it might be worth checking it as well. So that's what I'm going to do.
Here's the output from the ESR 78 code for CompositorOGL::EndFrame(). I've cut some of the output for brevity.
What would be great is if this build were to complete before the end of today because I want to run a new build of ESR 78 overnight. Rebuilding ESR 78 might sound a little crazy, after all I should be focusing on ESR 91. But as I've previously explained, I want to test out rendering to the background in different colours to establish more accurately where rendering is failing. Every thing I've tried up to now has had no effect on the output, but that's all been using ESR 91. I want to test the same things on ESR 78. That means making minimal changes to the ESR 78 code and doing a rebuild to test it on-device.
I can't think of a better way of doing this. I've come to the conclusion I just can't get the same results using the debugger alone. And so it is that I need to rebuild ESR 78.
With all these builds and plans for builds, I won't be able to do much more work on this today, so onward into the week to see how things progress.
If you'd like to read any of my other gecko diary entries, they're all available on my Gecko-dev Diary page.
Today I stumbled on a new thing to check. The code that swaps the buffer is an obvious area where things might be going wrong. And since there's not much of it and it all happens within the CompositorOGL::EndFrame() method in both versions (which, incidentally, share the same code almost identically) it seemed worth spending the time to check it.
So first up the actual code that swaps the buffers. The idea is that the previous rendered frame is held in one buffer; the next frame is rendered off screen and then swapped out for the old one. This ensures the swap happens fast, minimising the chance of artefacts and flicker appearing during the render cycle.
Here's a copy of the method for reference.
bool GLContextEGL::SwapBuffers() { EGLSurface surface = mSurfaceOverride != EGL_NO_SURFACE ? mSurfaceOverride : mSurface; if (surface) { if ((mEgl->IsExtensionSupported( GLLibraryEGL::EXT_swap_buffers_with_damage) || mEgl->IsExtensionSupported( GLLibraryEGL::KHR_swap_buffers_with_damage))) { std::vector<EGLint> rects; for (auto iter = mDamageRegion.RectIter(); !iter.Done(); iter.Next()) { const IntRect& r = iter.Get(); rects.push_back(r.X()); rects.push_back(r.Y()); rects.push_back(r.Width()); rects.push_back(r.Height()); } mDamageRegion.SetEmpty(); return mEgl->fSwapBuffersWithDamage(mEgl->Display(), surface, rects.data(), rects.size() / 4); } return mEgl->fSwapBuffers(mEgl->Display(), surface); } else { return false; } }Stepping through the code on ESR 78 this is what we get:
Thread 36 "Compositor" hit Breakpoint 1, mozilla::gl::GLContextEGL:: SwapBuffers (this=0x7eac109140) at gfx/gl/GLContextProviderEGL.cpp:643 643 bool GLContextEGL::SwapBuffers() { (gdb) n [Thread 0x7fa4afe9a0 (LWP 24091) exited] 644 EGLSurface surface = (gdb) n [New Thread 0x7fa467c9a0 (LWP 24117)] 646 if (surface) { (gdb) p surface $1 = (EGLSurface) 0x7eac004170 (gdb) n 647 if ((mEgl->IsExtensionSupported( (gdb) n 415 /opt/cross/aarch64-meego-linux-gnu/include/c++/8.3.0/bitset: No such file or directory. (gdb) 663 return mEgl->fSwapBuffers(mEgl->Display(), surface); (gdb)The really important thing to notice about this is that the condition checking support for EXT_swap_buffers_with_damage or KHR_swap_buffers_with_damage both fail. This means that the condition is skipped rather than being entered. You may recall that back on Day 83 we had to explicitly disable these two extensions and that it was the act of disabling them that resulted in the onscreen render pipeline working successfully for the first time.
It's therefore an obvious concern that this might be causing problems for the offscreen render pipeline as well. Clearly on ESR 78 these are disabled, but are they on ESR 91? Here's what we get when we try with ESR 91:
Thread 37 "Compositor" hit Breakpoint 1, mozilla::gl::GLContextEGL:: SwapBuffers (this=0x7ee019aa50) at gfx/gl/GLContextProviderEGL.cpp:662 662 bool GLContextEGL::SwapBuffers() { (gdb) n 663 EGLSurface surface = (gdb) 665 if (surface) { (gdb) p surface $1 = (EGLSurface) 0x7ee0004b60 (gdb) n [Thread 0x7f1f2fe7e0 (LWP 958) exited] 666 if ((mEgl->IsExtensionSupported( (gdb) 415 include/c++/8.3.0/bitset: No such file or directory. (gdb) 682 return mEgl->fSwapBuffers(surface); (gdb)This is almost identical to the ESR 78 output and crucially the extension condition is also being skipped. So I guess it's not this that's causing the problems for the offscreen render. Nonetheless I'm glad I checked.
While stepping through this I noticed that when stepping out of the SwapBuffers() method I end up in the CompositorOGL::EndFrame() method. This is also a pretty simple and linear method, so I figure it might be worth checking it as well. So that's what I'm going to do.
Here's the output from the ESR 78 code for CompositorOGL::EndFrame(). I've cut some of the output for brevity.
Thread 36 "Compositor" hit Breakpoint 3, mozilla::layers:: CompositorOGL::EndFrame (this=0x7eac003450) at gfx/layers/opengl/CompositorOGL.cpp:2000 2000 void CompositorOGL::EndFrame() { (gdb) n 2001 AUTO_PROFILER_LABEL("CompositorOGL::EndFrame", GRAPHICS); (gdb) n 2022 mShouldInvalidateWindow = false; (gdb) n 2024 if (mTarget) { (gdb) p mTarget $4 = {mRawPtr = 0x0} (gdb) n 2034 mWindowRenderTarget = nullptr; (gdb) n 2035 mCurrentRenderTarget = nullptr; (gdb) n 2037 if (mTexturePool) { (gdb) p mTexturePool $5 = {mRawPtr = 0x0} (gdb) n 2043 mGLContext->SetDamage(mCurrentFrameInvalidRegion); (gdb) n 2044 mGLContext->SwapBuffers(); (gdb) n 2045 mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); (gdb) n 2049 mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0 + i); (gdb) n 2050 mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, 0); (gdb) n 2051 if (!mGLContext->IsGLES()) { (gdb) n 258 obj-build-mer-qt-xr/dist/include/GLContext.h: No such file or directory. [...] (gdb) n 2056 mCurrentFrameInvalidRegion.SetEmpty(); (gdb) n 2058 Compositor::EndFrame(); (gdb)And here's the same on ESR 91. Once again, the execution flow, variables and output overall are almost identical.
Thread 37 "Compositor" hit Breakpoint 2, mozilla::layers:: CompositorOGL::EndFrame (this=0x7ee0002f10) at gfx/layers/opengl/CompositorO GL.cpp:2014 2014 void CompositorOGL::EndFrame() { (gdb) n 2015 AUTO_PROFILER_LABEL("CompositorOGL::EndFrame", GRAPHICS); (gdb) n 2035 mFrameInProgress = false; (gdb) n 2036 mShouldInvalidateWindow = false; (gdb) n 2038 if (mTarget) { (gdb) p mTarget $2 = {mRawPtr = 0x0} (gdb) n 2048 mWindowRenderTarget = nullptr; (gdb) n 2049 mCurrentRenderTarget = nullptr; (gdb) n 2051 if (mTexturePool) { (gdb) p mTexturePool $3 = {mRawPtr = 0x0} (gdb) n 2057 mGLContext->SetDamage(mCurrentFrameInvalidRegion); (gdb) n 2058 mGLContext->SwapBuffers(); (gdb) n 2059 mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0); (gdb) n 2063 mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0 + i); (gdb) n 2064 mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, 0); (gdb) n 2065 if (!mGLContext->IsGLES()) { (gdb) n 260 ${PROJECT}/obj-build-mer-qt-xr/dist/include/GLContext.h: No such file or directory. [...] (gdb) n 2070 mCurrentFrameInvalidRegion.SetEmpty(); (gdb) n [...] 2072 Compositor::EndFrame(); (gdb)That's all good. Both match up nicely as we might hope. With that dealt with it now really does feel like it's time to move on. To cement this segue I've set the ESR 91 build running. This will allow me to check the changes I made over the last few days to the GetAppDisplay() usage. For some reason every night for the last few nights I've forgotten to run the build which has prevented me from checking it.
What would be great is if this build were to complete before the end of today because I want to run a new build of ESR 78 overnight. Rebuilding ESR 78 might sound a little crazy, after all I should be focusing on ESR 91. But as I've previously explained, I want to test out rendering to the background in different colours to establish more accurately where rendering is failing. Every thing I've tried up to now has had no effect on the output, but that's all been using ESR 91. I want to test the same things on ESR 78. That means making minimal changes to the ESR 78 code and doing a rebuild to test it on-device.
I can't think of a better way of doing this. I've come to the conclusion I just can't get the same results using the debugger alone. And so it is that I need to rebuild ESR 78.
With all these builds and plans for builds, I won't be able to do much more work on this today, so onward into the week to see how things progress.
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