[Feature] (SharedImage): sample NV12/P010 dma-bufs through GL_OES_EGL_image_external on both backends, copying foreign buffers into server YUV images

This commit is contained in:
2026-10-03 22:46:00 -04:00
parent 4633ca223c
commit 7218bacb49
58 changed files with 2972 additions and 153 deletions
+43
View File
@@ -1517,6 +1517,8 @@ namespace MobileGL::MG_Remote::Server {
reply.Format = image.Fourcc;
reply.Stride = image.Stride;
reply.Offset = image.Offset;
reply.Plane1Stride = image.Plane1Stride;
reply.Plane1Offset = image.Plane1Offset;
};
switch (op.Op) {
case MG_Pipe::kMGPSharedImageAllocate: {
@@ -1554,6 +1556,33 @@ namespace MobileGL::MG_Remote::Server {
return false;
}
SI::ImageRef image = SI::Identify(fd, why);
// YUV: the planes and colour hints ride in Damage (MGPImportPlaneWord). A buffer this
// server did not allocate is taken too, through the labelled CPU-copy fallback
// (SharedImageRegistry.h, Image::ForeignSource); RGBA ones never are.
const Bool yuv = SI::FourccIsYuv(op.Format) && op.DamageCount == MG_Pipe::kMGPImportPlaneWords;
if (image == nullptr && yuv) {
SI::PlaneLayout layout;
layout.Count = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportPlaneCount]);
layout.Offset[0] = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportPlane0Offset]);
layout.Offset[1] = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportPlane1Offset]);
layout.Pitch[0] = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportPlane0Pitch]);
layout.Pitch[1] = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportPlane1Pitch]);
// The copy reads rows: only a buffer said to be linear (or said nothing) is one.
const Uint64 modifier =
static_cast<Uint64>(static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportModifierLo])) |
(static_cast<Uint64>(static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportModifierHi])) << 32);
if (op.Damage[MG_Pipe::kMGPImportHasModifier] != 0 && modifier != SI::kModifierLinear &&
modifier != SI::kModifierInvalid) {
char text[96];
std::snprintf(text, sizeof(text), "; a foreign buffer of modifier 0x%016llx is not linear",
static_cast<unsigned long long>(modifier));
why += text;
} else {
std::string foreignWhy;
image = SI::ImportForeignYuv(fd, op.Width, op.Height, op.Format, layout, foreignWhy);
if (image == nullptr) why += "; as a foreign YUV buffer: " + foreignWhy;
}
}
#if !defined(_WIN32)
::close(fd);
#endif
@@ -1561,6 +1590,20 @@ namespace MobileGL::MG_Remote::Server {
MGLOG_W_ONCE("MG_Remote server: a dma-buf import was refused: %s", why.c_str());
return false;
}
if (SI::FourccIsYuv(image->Fourcc) != SI::FourccIsYuv(op.Format) ||
(SI::FourccIsYuv(op.Format) && image->Fourcc != op.Format)) {
MGLOG_W("MG_Remote server: a dma-buf import of image %llu (fourcc 0x%08x) as fourcc 0x%08x was refused",
static_cast<unsigned long long>(image->Id), image->Fourcc, op.Format);
return false;
}
if (yuv) {
SI::Yuv::Hints hints;
hints.ColorSpace = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportYuvColorSpace]);
hints.Range = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportYuvRange]);
hints.SitingX = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportYuvSiting]) & 0xffffu;
hints.SitingY = static_cast<Uint32>(op.Damage[MG_Pipe::kMGPImportYuvSiting]) >> 16;
SI::SetYuvHints(*image, hints);
}
if (image->Width != op.Width || image->Height != op.Height || !SI::FourccSupported(op.Format)) {
MGLOG_W("MG_Remote server: a dma-buf import of image %llu (%ux%u) as %ux%u fourcc 0x%08x was refused",
static_cast<unsigned long long>(image->Id), image->Width, image->Height, op.Width, op.Height,