[Feature] (disaggregated): the default framebuffer on a host-framed surface is the host's frame

Three things this path needs that the server-owned one never did, each because the pixels are not
in an EGL surface this time:

 - The client's DEFAULT framebuffer has to resolve to the frame.  Four places bind the driver's 0
   for the default framebuffer; they now ask g_hostFrameFramebufferId, which is 0 everywhere except
   while a host-framed surface is current, where it is the frame's framebuffer.  Without this every
   draw would land in the pbuffer the context was made with - a surface nobody ever sees.

 - eglMakeCurrent binds the surface's own default framebuffer behind the engine's binding shadow, so
   the frame has to be put back after every make-current, with the shadow invalidated first: a bind
   the shadow thinks already happened never reaches the driver.

 - The bind itself goes through FramebufferImpl::BindFramebufferId, not a raw glBindFramebuffer, for
   the same reason - a raw bind leaves the shadow claiming the previous framebuffer.

Frame lifecycle is otherwise unchanged: the frame becomes the draw target when it arrives, and is
dropped after the host has been answered and has presented it.

Compiles and links (libMobileGL.so, libMobileGLServer.so, exit 0), deployed to the device, and the
container's client is rebuilding against it.  The run that shows Plasma through it is next.
This commit is contained in:
gold
2026-10-01 01:14:51 +08:00
parent 035f1b07ae
commit ead7a10b68
5 changed files with 145 additions and 6 deletions
@@ -87,6 +87,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
#endif
MG_External::EGLFunctionsTable g_EGLFuncs;
Uint g_hostFrameFramebufferId = 0;
MG_External::GLESFunctionsTable g_GLESFuncs;
MG_External::GLESCapabilities g_GLESCapabilities;
@@ -6515,7 +6516,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Through the shadow: a raw bind here would leave the shadow claiming
// the previous user FBO, false-skipping its next re-bind.
FramebufferImpl::BindFramebufferId(
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, 0);
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, g_hostFrameFramebufferId);
}
return;
}
@@ -6584,7 +6585,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
// Through the shadow: a raw bind here would leave the shadow claiming
// the previous user FBO, false-skipping its next re-bind.
FramebufferImpl::BindFramebufferId(
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, 0);
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, g_hostFrameFramebufferId);
}
}
@@ -6604,7 +6605,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
FramebufferImpl::g_integerColorDrawBufferMask = 0;
}
FramebufferImpl::BindFramebufferId(
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, 0);
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, g_hostFrameFramebufferId);
return;
}
@@ -6645,7 +6646,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
FramebufferImpl::g_integerColorDrawBufferMask = 0;
}
FramebufferImpl::BindFramebufferId(
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, 0);
target == FramebufferTarget::Draw ? GL_DRAW_FRAMEBUFFER : GL_READ_FRAMEBUFFER, g_hostFrameFramebufferId);
return;
}