using Ryujinx.Common;
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Ryujinx.HLE.HOS.Services.Android
{
[StructLayout(LayoutKind.Sequential, Size = 0x28)]
struct GraphicBufferHeader
public int Magic;
public int Width;
public int Height;
public int Stride;
public int Format;
public int Usage;
public int Pid;
public int RefCount;
public int FdsCount;
public int IntsCount;
}
[StructLayout(LayoutKind.Explicit, Size = 0x58)]
struct NvGraphicBufferSurface
[FieldOffset(0)]
public uint Width;
[FieldOffset(0x4)]
public uint Height;
[FieldOffset(0x8)]
public ColorFormat ColorFormat;
[FieldOffset(0x10)]
public int Layout;
[FieldOffset(0x14)]
public int Pitch;
[FieldOffset(0x18)]
public int NvMapHandle;
[FieldOffset(0x1C)]
public int Offset;
[FieldOffset(0x20)]
public int Kind;
[FieldOffset(0x24)]
public int BlockHeightLog2;
[FieldOffset(0x28)]
public int ScanFormat;
[FieldOffset(0x30)]
public long Flags;
[FieldOffset(0x38)]
public long Size;
[StructLayout(LayoutKind.Explicit)]
struct NvGraphicBufferSurfaceArray
[FieldOffset(0x0)]
private NvGraphicBufferSurface Surface0;
[FieldOffset(0x58)]
private NvGraphicBufferSurface Surface1;
[FieldOffset(0xb0)]
private NvGraphicBufferSurface Surface2;
public NvGraphicBufferSurface this[int index]
get
if (index == 0)
return Surface0;
else if (index == 1)
return Surface1;
else if (index == 2)
return Surface2;
throw new IndexOutOfRangeException();
[StructLayout(LayoutKind.Explicit, Size = 0x144)]
struct NvGraphicBuffer
public int NvMapId;
[FieldOffset(0xC)]
public int Type;
public int PixelFormat;
public int ExternalPixelFormat;
public int FrameBufferSize;
[FieldOffset(0x2C)]
public int PlanesCount;
[FieldOffset(0x34)]
public NvGraphicBufferSurfaceArray Surfaces;
struct GbpBuffer
public GraphicBufferHeader Header { get; private set; }
public NvGraphicBuffer Buffer { get; private set; }
public int Size => Marshal.SizeOf<NvGraphicBuffer>() + Marshal.SizeOf<GraphicBufferHeader>();
public GbpBuffer(BinaryReader reader)
Header = reader.ReadStruct<GraphicBufferHeader>();
// ignore fds
// TODO: check if that is used in official implementation
reader.BaseStream.Position += Header.FdsCount * 4;
if (Header.IntsCount != 0x51)
throw new NotImplementedException($"Unexpected Graphic Buffer ints count (expected 0x51, found 0x{Header.IntsCount:x}");
Buffer = reader.ReadStruct<NvGraphicBuffer>();
public void Write(BinaryWriter writer)
writer.WriteStruct(Header);
writer.WriteStruct(Buffer);