[MG_Remote] keep synchronous pack replies authoritative in the client buffer

This commit is contained in:
2026-09-20 12:01:01 -04:00
parent 1113298195
commit 44cac27bbc
3 changed files with 5 additions and 12 deletions
@@ -3096,18 +3096,9 @@ namespace MobileGL::MG_Impl::GLImpl {
void ReadPixels_Backend(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
MGP_FILL(ReadPixels);
MG_Backend::gBackendFunctionsTable.GL.ReadPixels(x, y, width, height, format, type, pixels);
#if MOBILEGL_BUILD_DISAGGREGATED
// P5 (b1), one of the two producers the client-side GPU-write set ADDS. A read into a
// bound GL_PIXEL_PACK_BUFFER is a GPU write to that buffer exactly as a shader's store
// is, and marking it is what makes the next glMapBuffer / glGetBufferSubData of the
// PBO reconcile. It is a no-op on the monolith path, where the backend still maps the
// PBO and copies it into the shadow inside the call
// (DirectGLES.cpp:10983-10993) - an unconditional stall on every glReadPixels whether
// or not anything ever reads the shadow. Deferring that to the first read that wants
// it is STRICTLY BETTER, which is the only reason a split build is allowed to differ
// here at all.
MG_Remote::Client::MarkReadPixelsPackBuffer();
#endif
// The split emitter waits for an owned pixel reply, then uploads its
// packed rows into the client PBO. Its shadow is already authoritative;
// marking another GPU write here would invent a readback that never ran.
}
/* @INSERTION_POINT:FUNCTION_IMPLEMENTATION@ */
+1
View File
@@ -1009,6 +1009,7 @@ namespace MobileGL::MG_Remote::Client {
if (pbo) {
// pixels is an offset, never a host pointer. Upload only the
// requested rows so PACK padding and untouched bytes survive.
pbo->SyncGpuWrites();
const Uint64 alignment = std::max<Int>(pack.Alignment, 1);
const Uint64 rowPixels = pack.RowLength > 0 ? pack.RowLength : width;
const Uint64 stride = (rowPixels * bytesPerPixel + alignment - 1) / alignment * alignment;
@@ -94,6 +94,7 @@
offset += info.DstSize;
}
ApplyReadbackByteSwap(bytes.data(), tight, type, pack);
if (pbo) pbo->SyncGpuWrites();
for (Uint64 z = 0; z < depth; ++z) {
for (Int y = 0; y < size.y(); ++y) {
Uint8* source = bytes.data() + (z * size.y() + y) * layout.RowBytes;