XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Runtime.InteropServices;

namespace XFESystem.Boot
{
    // Version 1 intentionally keeps the existing fixed-width firmware handoff.
    // It contains original EDID/path bytes, never pointers to temporary firmware data.
    [StructLayout(LayoutKind.Sequential)]
    public struct DisplayMode
    {
        public uint Id, Width, Height, StridePixels, BitsPerPixel, Flags;
        public bool IsValid => (Flags & 1) != 0 && Width >= 320 && Width <= 16384 &&
            Height >= 200 && Height <= 16384 && StridePixels >= Width &&
            (BitsPerPixel == 24 || BitsPerPixel == 32) &&
            (ulong)StridePixels * Height * BitsPerPixel / 8 <= 256 * 1024 * 1024;
    }

    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct DisplayRecord
    {
        public ulong FramebufferBase, FramebufferBytes, Handle;
        public uint ModeCount, FirmwareModeCount, SelectedMode, OriginalMode;
        public uint Width, Height, Flags, SetStatus, EdidBytes, EdidSource, PathBytes, Choice;
        public uint StridePixels, PixelFormat, RedMask, GreenMask, BlueMask, RequestedMode;
        public fixed byte Modes[128 * 24];
        public fixed byte Edid[4096];
        public fixed byte Path[256];
    }

    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct DisplayHandoff
    {
        public const int MaximumDisplays = 8, MaximumModes = 128;
        public const uint FinalGeometry = 256, BootloaderChangedMode = 512, SelectedModeHint = 1024;
        public ulong Magic;
        public uint Version, Bytes, DisplayCount, DisplayControllers, ConnectFailures, Flags;
        public fixed byte Displays[8 * 7520];
    }

    public static unsafe class DisplayPolicy
    {
        public static bool IsEdidValid(byte* edid, uint bytes)
        {
            if (edid == null || bytes < 128 || bytes > 4096 || edid[0] != 0 || edid[7] != 0 || edid[18] != 1)
                return false;
            for (int i = 1; i < 7; i++) if (edid[i] != 255) return false;
            byte sum = 0;
            for (int i = 0; i < 128; i++) sum = (byte)(sum + edid[i]);
            return sum == 0;
        }

        static bool DetailedMatches(byte* data, uint width, uint height) =>
            (data[0] != 0 || data[1] != 0) &&
            ((uint)data[2] | ((uint)(data[4] & 0xF0) << 4)) == width &&
            ((uint)data[5] | ((uint)(data[7] & 0xF0) << 4)) == height;

        public static bool EdidAdvertises(byte* edid, uint bytes, uint width, uint height)
        {
            if (!IsEdidValid(edid, bytes)) return false;
            for (int at = 54; at + 18 <= 126; at += 18)
                if (DetailedMatches(edid + at, width, height)) return true;
            for (int at = 38; at < 54; at += 2)
            {
                if (edid[at] <= 1) continue;
                uint w = ((uint)edid[at] + 31) * 8;
                uint aspect = (uint)(edid[at + 1] >> 6);
                uint h = aspect == 0 ? w * 10 / 16 : aspect == 1 ? w * 3 / 4 : aspect == 2 ? w * 4 / 5 : w * 9 / 16;
                if (w == width && h == height) return true;
            }
            uint blocks = edid[126] < 31 ? edid[126] : 31u;
            for (uint block = 0; block < blocks && (block + 2) * 128 <= bytes; block++)
            {
                byte* data = edid + (block + 1) * 128;
                byte sum = 0;
                for (int i = 0; i < 128; i++) sum = (byte)(sum + data[i]);
                uint end = data[2];
                if (data[0] != 2 || sum != 0 || end < 4 || end > 127) continue;
                for (uint at = end; at + 18 <= 127; at += 18)
                    if (DetailedMatches(data + at, width, height)) return true;
                uint cursor = 4;
                while (cursor < end)
                {
                    uint length = (uint)(data[cursor] & 31), kind = (uint)(data[cursor] >> 5);
                    cursor++;
                    if (cursor + length > end) break;
                    if (kind == 2)
                        for (uint i = 0; i < length; i++)
                        {
                            uint w, h;
                            VicResolution((uint)(data[cursor + i] & 127), out w, out h);
                            if (w == width && h == height && w != 0) return true;
                        }
                    cursor += length;
                }
            }
            return false;
        }

        static void VicResolution(uint id, out uint width, out uint height)
        {
            width = height = 0;
            if (id == 1) { width = 640; height = 480; }
            else if (id == 2 || id == 3 || id == 6 || id == 7 || id >= 48 && id <= 51 || id >= 56 && id <= 59) { width = 720; height = 480; }
            else if (id == 4 || id == 19 || id == 41 || id == 47 || id >= 60 && id <= 62 || id >= 65 && id <= 71 || id == 108 || id == 109) { width = 1280; height = 720; }
            else if (id == 5 || id == 16 || id == 20 || id >= 31 && id <= 34 || id == 39 || id == 40 || id == 46 || id == 63 || id == 64 || id >= 72 && id <= 78 || id == 110 || id == 111) { width = 1920; height = 1080; }
            else if (id == 17 || id == 18 || id == 21 || id == 22 || id >= 42 && id <= 45 || id >= 52 && id <= 55) { width = 720; height = 576; }
            else if (id >= 79 && id <= 85 || id == 112) { width = 1680; height = 720; }
            else if (id >= 86 && id <= 92 || id == 113) { width = 2560; height = 1080; }
            else if (id >= 93 && id <= 97 || id >= 103 && id <= 107 || id == 114 || id >= 116 && id <= 120) { width = 3840; height = 2160; }
            else if (id >= 98 && id <= 102 || id == 115) { width = 4096; height = 2160; }
            else if (id >= 121 && id <= 127) { width = 5120; height = 2160; }
        }

        public static uint ChooseMode(DisplayMode* modes, uint count, byte* edid, uint edidBytes, uint fallback)
        {
            if (modes == null || count > DisplayHandoff.MaximumModes) return fallback;
            bool restrict = false;
            for (uint i = 0; i < count; i++)
                if (modes[i].IsValid && EdidAdvertises(edid, edidBytes, modes[i].Width, modes[i].Height)) restrict = true;
            DisplayMode best = default;
            bool found = false;
            for (uint i = 0; i < count; i++)
            {
                DisplayMode candidate = modes[i];
                if (!candidate.IsValid || restrict && !EdidAdvertises(edid, edidBytes, candidate.Width, candidate.Height)) continue;
                ulong area = (ulong)candidate.Width * candidate.Height, previous = (ulong)best.Width * best.Height;
                if (!found || area > previous || area == previous && (candidate.Width > best.Width || candidate.Width == best.Width &&
                    (candidate.Height > best.Height || candidate.Height == best.Height && (candidate.BitsPerPixel > best.BitsPerPixel ||
                    candidate.BitsPerPixel == best.BitsPerPixel && candidate.Id < best.Id))))
                { best = candidate; found = true; }
            }
            return found ? best.Id : fallback;
        }
    }
}