mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-16 06:23:23 +09:00
[Docs] (P12): the on-screen server window's plan, audit, harness and device evidence move into the tree, and the status page says what this line is and what it still owes - CURRENT_STAGE_STATUS records that the P12 subset is implemented but NOT handed off (both exit gates unrun: no cross-machine TCP, no FCL + kill-server device-lost), the ROADMAP P12 row stops reading "待排", and notes/p12 carries the brief, the four read-only audits, the gate and device harness, and the curated device evidence (check transcripts, replay verdicts, on-screen captures; logcat left out per notes/README.md's evidence-data rule)
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
|
||||
// P12 (on-screen server window): A SERVER SESSION ENDS IN A PROCESS THAT OUTLIVES IT.
|
||||
//
|
||||
// The in-process display server (the display Activity's process) runs its sessions one after
|
||||
// another in ONE process, and each new client mints its handles from the same {slot, gen} space
|
||||
// again. The twin tables are process globals, so the twins the previous session built - naming ids
|
||||
// of the context its backend destroyed - answered for the next session's objects: on the device
|
||||
// the second on-screen OpenRA replay linked no program (ssim 0.00004) and the third crashed inside
|
||||
// Adreno's glDrawElements; on llvmpipe the second replay failed the same way. The server backend's
|
||||
// destruction under a transport - the end of a session - now drops every twin (without a driver
|
||||
// call), and monolith keeps its twins. Red once: remove the DropEveryTwinForEndedServerSession
|
||||
// call from ~BackendObject_DirectGLES and the first half of this case fails at every kind.
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
TEST(EsprytServerSession, TheServerBackendsDestructionDropsEveryTwinTheSessionBuilt) {
|
||||
using namespace MobileGL;
|
||||
namespace GL = MG_Backend::DirectGLES;
|
||||
const auto previousTransport = MG_Config::Transport;
|
||||
const MG_Pipe::MGPipeHandle program{7u, 3u};
|
||||
const MG_Pipe::MGPipeHandle texture{4u, 2u};
|
||||
const MG_Pipe::MGPipeHandle buffer{5u, 1u};
|
||||
// A session's twins: LIVE entries at the generations its client minted. A null twin object is
|
||||
// enough for the program and texture kinds - what the next session trips over is the live
|
||||
// entry itself (its generation, and the driver id a real twin would carry).
|
||||
const auto populate = [&] {
|
||||
ASSERT_NE(GL::PrgramImpl::g_backendProgramObjects.GetOrCreateByHandle(program), nullptr);
|
||||
ASSERT_NE(GL::TextureImpl::g_backendTextureObjects.GetOrCreateByHandle(texture), nullptr);
|
||||
GL::BufferImpl::g_backendBufferResources.GetOrCreate(buffer) =
|
||||
MakeShared<GL::BufferImpl::GLESBufferResource>();
|
||||
ASSERT_EQ(GL::PrgramImpl::g_backendProgramObjects.LiveGenAt(program.Slot), 3u);
|
||||
ASSERT_EQ(GL::TextureImpl::g_backendTextureObjects.LiveGenAt(texture.Slot), 2u);
|
||||
ASSERT_NE(GL::BufferImpl::g_backendBufferResources.FindByHandle(buffer), nullptr);
|
||||
};
|
||||
|
||||
// Under a transport this backend is the SERVER's: its destruction ends the session.
|
||||
MG_Config::Transport = MG_Config::TransportMode::Spawn;
|
||||
populate();
|
||||
{ GL::BackendObject_DirectGLES serverBackend; }
|
||||
EXPECT_EQ(GL::PrgramImpl::g_backendProgramObjects.LiveGenAt(program.Slot), 0u)
|
||||
<< "the ended session's program twin is still live: the next session's client mints {7, 0} "
|
||||
"and is refused as ProtocolCorruption, or adopts a program of the destroyed context";
|
||||
EXPECT_EQ(GL::TextureImpl::g_backendTextureObjects.LiveGenAt(texture.Slot), 0u)
|
||||
<< "the ended session's texture twin is still live";
|
||||
EXPECT_EQ(GL::BufferImpl::g_backendBufferResources.FindByHandle(buffer), nullptr)
|
||||
<< "the ended session's buffer twin is still live";
|
||||
// The next session starts from empty tables: its first handle at that slot is a fresh twin.
|
||||
MG_Pipe::MGPipeHandle nextSession{7u, 0u};
|
||||
auto* fresh = GL::PrgramImpl::g_backendProgramObjects.GetOrCreateByHandle(nextSession);
|
||||
ASSERT_NE(fresh, nullptr);
|
||||
EXPECT_EQ(*fresh, nullptr);
|
||||
|
||||
// Monolith keeps its twins: its backend is not a session's, and nothing here changed for it.
|
||||
GL::PrgramImpl::g_backendProgramObjects = {};
|
||||
MG_Config::Transport = MG_Config::TransportMode::Monolith;
|
||||
populate();
|
||||
{ GL::BackendObject_DirectGLES monolithBackend; }
|
||||
EXPECT_EQ(GL::PrgramImpl::g_backendProgramObjects.LiveGenAt(program.Slot), 3u);
|
||||
EXPECT_EQ(GL::TextureImpl::g_backendTextureObjects.LiveGenAt(texture.Slot), 2u);
|
||||
EXPECT_NE(GL::BufferImpl::g_backendBufferResources.FindByHandle(buffer), nullptr);
|
||||
|
||||
GL::PrgramImpl::g_backendProgramObjects = {};
|
||||
GL::TextureImpl::g_backendTextureObjects = {};
|
||||
GL::BufferImpl::g_backendBufferResources = {};
|
||||
MG_Config::Transport = previousTransport;
|
||||
}
|
||||
#else
|
||||
TEST(EsprytServerSession, TheServerBackendsDestructionDropsEveryTwinTheSessionBuilt) {
|
||||
GTEST_SKIP() << "a server backend exists only in the split build (MOBILEGL_BUILD_DISAGGREGATED)";
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user