• Jeffrey Lee's avatar
    Attempt to tidy up substitute screen mode selection logic · d87c22a4
    Jeffrey Lee authored
      Over the years the OS's substitute screen mode selection logic has grown to be a tangled mess, and the logic it does implement isn't always very useful. Additionally, the kernel is structured in such a way that it can be hard for modules to override it.
      This set of changes aims to fix the many of the problems, by doing the following:
      - Moving all substitute mode selection logic out of the core VDU driver code and into a Service_ModeTranslation handler. This means you now only have one place in the kernel to look instead of several, and modules can override the behaviour by claiming/blocking the service call as appropriate.
      - Moving handling of the built-in VIDC lists out of the core VDU driver code and into a Service_ModeExtension handler. This means programs can now inspect these VIDC lists by issuing the right service call (although you are essentially limited to lists which the GraphicsV driver is OK with)
      - Moving *TV interlace & offset adjustment logic into the Service_ModeExtension handler, since they're legacy things which can be handled more cleanly for MDF/EDID (and the old code was poking memory the kernel didn't own)
      - Adding a Service_EnumerateScreenModes implementation, so that if you end up in the desktop with ScreenModes non-functional, the display manager at least has something useful to show you
      - Enhancing the handling of the built-in numbered modes so that they are now available in any colour depth; the Service_ModeExtension handler (and related handlers) treat the builtin VIDC lists as a set of mode timings, not a discrete set of modes
      - Substitute mode selection logic is a complete re-write. Instead of trying a handful of numbered fallback modes, it now tries:
        - Same mode but at higher colour depths
        - Same mode but at lower colour depths
        - Alternate resolutions (half-width mode with no double-pixel if original request was for double-pixel, and default resolution for monitor type)
      - Combined with the logic to allow the builtin VIDC lists to be used at any colour depth, this means that the kernel should now be able to find substitute modes for machines which lack support for <=8bpp modes (e.g. OMAP5)
      - Additionally the mode substitution code will attempt to retain as many properties of the originally requested mode as possible (eigen values, gap mode type, etc.)
      Other improvements:
      - The kernel now actually vets the builtin VIDC lists instead of assuming that they'll work (which also means they'll have the correct ExtraBytes value, where applicable)
      - The kernel now uses GraphicsV 19 (VetMode2) to vet the mode during the mode switch process, using the result to detect where the framebuffer will be placed. This allows for GraphicsV drivers to switch between DA 2 and external framestores on a per-mode basis.
      - The kernel now supports mode selectors which specify LineLength values which are larger than necessary; this will get translated to a suitable ExtraBytes control list item (+ combined with whatever padding the driver indicates is necessary via the VetMode2 result)
      File changes:
      - hdr/KernelWS - Reserve space for a VIDC list, since the Service_ModeExtension implementation typically can't use the built-in list as-is
      - s/Arthur3 - Issue Service_ModeFileChanged when the configured monitor type is changed, so that DisplayManager + friends are aware that the set of available modes has changed
      - s/GetAll - Fiddle with GETs a bit
      - s/MemMap2 - Extra LTORG
      - s/NewIRQs - Small routine to install/uninstall false VSync routine (previously from PushModeInfo, which wasn't really the appropriate place for it)
      - s/Utility - Hook up the extra service call handlers
      - s/vdu/legacymodes - New file containing the new service call implementations, and some related code
      - s/vdu/vdudecl - Move mode workspace definition here, from vdumodes
      - s/vdu/vdudriver - Remove assorted bits of mode substitution code. Plug in new bits for calling GraphicsV 19 during mode set, and deal with ExtraBytes/LineLength during PushModeInfo
      - s/vdu/vdumodes - Move some workspace definitions to s/vdu/vdudecl. Tweak how the builtin VIDC lists are stored.
      - s/vdu/vduswis - Rip out more mode substitution code. Issue Service_ModeFileChanged when monitor type is changed by OS_ScreenMode.
      Tested on Raspberry Pi 3, Iyonix, IGEPv5
    Version 6.14. Tagged as 'Kernel-6_14'
VersionASM 1006 Bytes