Details of new OS_ScreenMode calls are given in each individual section of the document.
New reason codes are numbered from 64+, to avoid clashing with ROL’s allocations which are numbered from 255 down.
(n.b. having multiple displays active at once, e.g. multi-display desktop, is not covered in this section)
The pointer overlay is set by one of a number of routes:
These APIs all enforce a maximum pointer size of 32×32 pixels and a colour depth of 2bpp. However a 32×32 pointer is likely to be insufficient for 180 DPI modes (the standard 11×22 pointer image, when scaled up, would be 22×44). Furthermore, most modern display hardware allows for true-colour, alpha-blended pointer overlays – but the 2bpp limitation of the current APIs prevents any such features from being used under RISC OS.
Internally the kernel buffers the 32×32×2bpp pointer images and allows drivers to reference the buffered data directly. This is favourable for the VIDC driver as the buffering code was designed specifically for that hardware. However for all other current drivers this is a useless feature, as the data must be converted to different hardware-specific forms before use.
A new feature flag will be required to allow drivers to indicate that they use the new pointer API.
Entry | |
---|---|
R0 | Shape number (0-3) |
R1 | Pointer to request block |
R4 | Reason code, driver number, etc. |
Exit | |
---|---|
- | Request block updated as appropriate |
This call will allow the caller to query a driver’s level of support for a given pointer image. It operates on a request block with the following format:
Word | |
---|---|
0 | Desired image type |
0 = 2bpp | |
1 = true-colour transparency mask | |
2 = true-colour alpha blended | |
1 | Desired width |
2 | Desired height |
3 | NColour value |
4 | ModeFlags value |
5 | Log2BPP value |
On entry, words 0-2 should be filled in. On exit, the driver will have updated words 0-2 to match its abilities, and filled in words 3-5 to describe the required pixel format of the shape data. For example, the VIDC20 driver will set the image to 0, set the image width to 32, and clamp the image height to within a sensible limit. Words 3-5 will describe a 2bpp mode.
Entry | |
---|---|
R0 | Shape number (0-3) |
R1 | Pointer to request block (as above) |
R4 | Reason code, driver number, etc. |
Exit | |
---|---|
- | Request block updated as appropriate |
R2 | Pointer to image buffer |
R3 | Stride of buffer rows |
This call is used to allocate a shape buffer. The stride value returned in R3 is the number of bytes from the start of one row to the start of the next. The caller is expected to fill in the buffer with data in the format requested, which is not guaranteed to match the format that was returned from an earlier call to GraphicsV PointerFeatures. Any pixels/bytes which lie outside the image (for if the stride in R3 is larger than width*bpp) must not be modified.
Entry | |
---|---|
R0 | Shape number (0-3) |
R1 | Pointer to image buffer |
R2 | X position of active point |
R3 | Y position of active point |
R4 | Reason code, driver number, etc. |
Exit | |
---|---|
- | All registers preserved |
This call is used to return a buffer to the driver once it has been filled in. The active point of the image is also specified (as per OS_Word 21_0).
If the caller was updating the shape data for the image currently being displayed, it is the driver’s responsibility to ensure that the changes are buffered correctly such that there is an instantaneous transition from the old shape to the new; i.e. buffers which are currently being written to must not be displayed.
Entry | |
---|---|
R0 | Shape number (0-3) |
R1 | X coordinate |
R2 | Y coordinate |
R4 | Reason code, driver number, etc. |
Exit | |
---|---|
- | All registers preserved |
This call is used to select the displayed shape number and/or move the image on the screen.
Entry | |
---|---|
R4 | Reason code, driver number, etc. |
Exit | |
---|---|
- | All registers preserved |
This call is used to hide the pointer.
Allow the scale of the pointer image to be specified.
In order to fully support multiple active drivers, heads, and overlays, we need to overhaul how screen memory is managed.
At the moment the OS is in charge of memory management for the current driver:
This topic is covered in its own proposed implementation page.
The primary goal is to provide a fully-featured API to allow hardware overlays (particularly YUV) to easily be used by user applications, e.g. movie players. The API must allow for both windowed and full-screen use.
Other, more complex use cases are not to be considered at this stage.
To allow for multiple display setups, the API is designed to allow for one overlay to appear on multiple displays, at different positions and scales. It is the driver’s responsibility to provide support for this feature as best it can.
On some hardware (e.g. Raspberry Pi) we do not have direct access to the overlay hardware. We can only use a resource-based API which allows overlays to be allocated to us and their contents updated. Memory management is 100% under the control of the GPU. Due to this it’s proposed that the GraphicsV overlay interface uses a similar resource-based approach. Specifically, it’s expected that the following calls will be required:
In:
Out:
This call is used to allocate an overlay resource. The overlay is initially hidden and must be explicitly shown using the SetOverlayPosition call.
In:
Out:
This call is used to free an overlay resource
In:
Out:
This call is used to update the position information of an overlay, specifying the position across all heads at once to allow the driver to reconfigure the overlay in the most efficient manner. On exit the actual used position information will be returned, to e.g. allow a window to resize itself correctly to avoid any gaps around the edge of the overlay if the driver wasn’t able to provide the exact scale factor requested.
In:
Out:
This call is used to lock a buffer for update by the CPU. An overlay can only be locked by one user at a time; a subsequent lock attempt without an unlock will return an error.
In:
Out:
This call unlocks an overlay buffer. However, in a multi-buffered overlay it does not schedule the new contents to be displayed.
In:
Out:
In a multi-buffered overlay this call will submit the updated buffer for display by the GPU. Even in a single-buffered overlay this call is important, as the driver may use it to e.g. flush data from the CPU cache.
Calls will be needed for setting the palette and gamma tables used by the overlay. For the palette it makes sense to reuse the existing palette calls; therefore it’s proposed that overlay IDs are allocated by drivers such that they do not intersect the range of IDs used for heads. This will allow calls such as the palette ones to accept either a head ID or an overlay ID in bits 16-23 of R4.
On some hardware it’s possible to directly specify the YUV → RGB conversion matrix. Allowing this matrix to be specified at overlay creation time may be advantageous.
It may also be desirable to have the following calls available:
User software is to be discouraged from using the GraphicsV API directly. Instead, particularly for software running in the desktop, it’s expected that another API is to be used. Specifically the API used for the desktop must allow overlays to be associated with windows, such that the OS can automatically calculate the depth values of the overlays in response to the windows moving through the window stack. The overlay position will also be updated automatically as the windows are moved and scrolled, and the scale factor could be linked to the work area size.
A SWI call is also required to allow a window (or any other portion of the screen) to be filled with the correct colour to allow the overlay to be visible through it. For example to clear the alpha channel to zero or to write the correct colour value for systems which use a transparency colour key. For a software emulation of overlays this SWI could instead be used to directly plot the software overlay to the screen (e.g. use OS_SpriteOp calls to plot a YUV sprite).
For full-screen applications another API may be required, perhaps in the form of new OS_ScreenMode reason codes. To reduce code duplication it may make sense for user software (whether single or multi-tasking) to use OS_ScreenMode to create and update the contents of overlays. For multi-tasking software a Wimp SWI could be used to associate the overlay with a window, at which point the Wimp will automatically make SetOverlayPosition calls as appropriate. The Wimp could also be made to automatically destroy the overlay when the application dies.
Some systems (e.g. OMAP) only have a handful of overlays available, and their abilities are further restricted by the fact that the desktop and mouse cursor are overlays as well. This means that that the overlays available can vary wildly by screen more or active head(s). Therefore it is permitted for drivers to destroy any overlays they wish when switching screen modes, or when the ClaimOS call is received. A service call or some other notification method will be required in order to allow drivers to communicate overlay destruction to the owner of said overlay – exact details TBD.
Improve screen output redirection support so that screen output can be redirected to overlay memory buffers. This may be a fairly simple API change, as redirecting output to an arbitrary memory buffer shouldn’t be much different to redirecting to a sprite – we just need the ability to use a buffer which doesn’t have a sprite header attached. The ability to redirect output to an arbitrary buffer will also ease the implementation of the new pointer API (at the moment, OS_SpriteOp 36 creates the pointer image by redirecting output to a 2bpp sprite. For the new interface, redirecting output directly to the pointer memory buffer would be desirable in order to avoid temporary memory allocations)
Add support for plotting of YUV sprites to SpriteExtend, and add a software emulation layer to the user-facing overlay API, so that software can elect to use software emulation of overlays if a suitable hardware overlay is unavailable.
Provide a method to query whether a display is currently connected to a head. Provide a method to allow connection or disconnection of displays to be automatically detected and communicated to the system, e.g. via service call.
Add a new GraphicsV call to perform on-demand display detection:
Note that under the current multi-head specification, the S-Video and Composite outputs of the Pandora are to be treated as separate heads. Display detection for these outputs is supported, but the hardware is incapable of determining which of the two outputs the display is connected to. It may therefore be desirable to be able to communicate these limitations to the caller in the result buffer, e.g. listing the connection state of multiple heads at once.
API TBD. Care needs to be taken with power saving; e.g. TV-out detection on OMAP is only possible if the TV-out circuitry is on and generating a video signal. Leaving this running all the time could place an unnecessary drain on the battery of portable systems. Therefore it’s suggested that automatic detection is performed either entirely at the discretion of the driver, or a method is available to enable/disable detection at the user’s request (i.e. discourage the development of software which enables automatic detection for long periods of time without the user’s permission). The service call which is used to notify the system of connection state changes can also be used to notify the system of automatic detection starting/stopping.
The kernel should make use of the display detection functionality to decide which display to use on startup. The display manager and screen setup plugins can be updated to display the connection state of each display, potentially filtering out or listing separately any outputs for which no display is detected.
The overlay API will allow for scaling and rotation of overlays. However an API to allow scaling and rotation of the desktop (and implicitly the mouse pointer) is desirable.
New feature flags (e.g. as part of GraphicsV 8) will be required to allow drivers to advertise that they support the feature.
Add several new VIDC control list items to allow the framebuffer size and rotation to be specified. The timing parameters of the VIDC list will remain as-is, specifying the actual timings to be used when generating the video signal.
Control list items will also be required to specify the method of scaling – i.e. the coordinates of the rectangle (in physical pixels) in which the frame buffer is to be scaled to fit.
New mode string attributes can be added to allow the user to select scaling and rotation when selecting screen modes. How this maps to mode specifier blocks is TBD – new mode variables, mode flags, or a new mode specifier block format may be required. The display manager and screen setup plugin will also need updating to allow selection of rotation. Since rotation is unlikely to be changed very often, it makes sense for the screen setup plugin to allow the user to configure the default rotation of the display. Any modes which do not explicitly specify a rotation can then have the default rotation value filled in by ScreenModes when it generates the VIDC list.
How overlay positions are specified when dealing with a scaled/rotated desktop is TBD; are they specified relative to the desktop overlay, or are they specified relative to physical monitor pixels? Specifying relative to the desktop would be the most appropriate for most software, but specifying relative to physical pixels may be desirable for some use cases. A flag at the time of overlay creation could potentially be used to control the coordinate space that it used, and for completeness it may make sense to allow any arbitrary head/overlay to be used as the parent. Care may also be required with respect to rotation; what if the user wants an overlay to be rotated on one display, but unrotated on the other?
If a driver supports scaling, allow the system to automatically scale the display, to allow almost any mode to be used without requiring it to be listed in the MDF – i.e. as per AnyMode
If a display is able to sense its rotation/orientation (e.g. accelerometer in a mobile device), consider adding an “automatic” rotation mode to the OS where the desktop orientation will always match the physical orientation of the display.
Improve or replace the vet mode call, to allow drivers to provide feedback on why certain modes have been rejected. Feedback should be designed such that software can interpret it and make an informed decision on how to adjust the mode timings in order to arrive at a mode which is supported. E.g. the call could return a series of flags of the form “pixel rate too high”, “complex constraint between vertical sync with and vertical front porch”, etc. This feedback would be particularly useful when generating a set of screen modes from EDID.
A call should also be available to query which control list items a driver understands, and drivers should be updated to ensure they reject any VIDC list containing items which they don’t claim to understand.
TBD.
The RISC OS desktop is composed almost entirely of sprites. Therefore most of the CPU time associated with redrawing the desktop is spent either generating translation tables for sprites, drawing complex sprites (translation tables/pixel format conversion required), or doing direct memcpy’s of pre-translated sprites. A method for creating and rendering sprites using the GPU should be able to significantly reduce the CPU cost involved in redrawing the desktop and as well as the overall redraw time.
There are two ways the GraphicsV API could be implemented – as a cache-based system where the driver is free to release the sprite whenever it wishes (e.g. if the current palette changes, or to free up screen memory to allow for a mode change or creation of an overlay), or as a locked resource based system (where the driver must keep the sprite resident and valid until the caller allows it to be freed). If the cache approach is used then care must be taken to ensure the API isn’t designed in such a way that a user can successfully create a GPU optimised sprite only for the driver to throw it away just before the user has a chance to render it. If this happened the user would then have to try recreating it (which may fail again) or fall back to software rendering (which is what we’re trying to avoid altogether).
One key aspect feature of API should be that the driver must be explicitly told about any changes that have been made to the sprite. Direct access to the GPU optimised sprite is also likely to be forbidden; instead the API should be a one-way street where the caller passes in an OS sprite and gets a handle to a GPU sprite as a result. That same handle can be used to update the sprite (by passing in a new/updated OS sprite), but to give the driver freedom to store the GPU sprite in whatever format it wishes there should be no way for the caller to perform fine-grain actions such as updating individual pixels. The sprite update API can employ hints to reduce the amount of work the driver performs when updating the sprite. Hints should be forward-compatible such that drivers can ignore unknown hints; i.e. hints should describe what features of the sprite haven’t changed, rather than the features which have.
For a locked resource based API where the driver has to regenerate the GPU sprite after palette changes, etc., it makes sense for the driver to be able to directly reference the source sprite rather than forcing it to create its own internal copy. However this should be under the control of the caller, and the caller must notify the driver if he needs to move/modify the source sprite (for example via “DelinkSourceSprite”, “RelinkSourceSprite” calls)
An OS_SpriteOp-like API for interacting with GPU sprites would be desirable, and would ease transition to the new system. Whether the sprites are accelerated or not could be hidden away behind the scenes, allowing for the new API to be used irrespective of whether acceleration is currently possible or not. E.g. if the screen is being rendered to then GPU sprites would be used where possible. But if screen output is redirected to a sprite then software rendering would be used.
Care will also need to be taken as not all GPUs/drivers will be capable of all sprite operations, e.g. transparency masks, alpha blending, GCOL actions, or scaling. In particular, lack of hardware scaling can be at least be partially worked around in software, if the driver is either (a) told at sprite creation time what scale factor(s) that sprite is to be used at, or (b) allowed to generate scaled copies at render time (perhaps with a hint at creation time indicating how many scaled copies to maintain).
To make the most of the new feature, at least the following modules will need updating to use it where possible:
PAL/NTSC/etc. encoding and sending of a widescreen selection signal could be specified by VIDC control list item. See this thread for some related discussion.
For HDMI sources, we need a unified way of controlling whether HDMI or DVI signalling is used, or whether the choice is automatic. HDMI also allows the source to indicate the intended aspect ratio of the picture (within the limited set of aspect ratios defined by the spec); a new VIDC control list item to indicate the aspect ratio would be advantageous, perhaps along with a new mode variable and mode string/specifier changes (using eigen values to identify pixel aspect ratio is not always accurate)
HDMI sources generally support pixel repetition, to allow display of modes where the pixel clock rate is lower than the minimum supported rate, or to boost the bandwidth available to other data such as audio. Although much of the support for this might be automatic (fully within the driver when it’s asked to switch to a low-rate mode), some external control may also be required (disabling the feature if the monitor doesn’t maintain the correct aspect ratio, or controlling whether pixel repetition will be used to ensure that high-bandwidth audio is always available, etc.)
TV offset (as controlled by *TV) and overscan settings (for any kind of interface – TV-out, HDMI etc.) need to be taken into account. At the moment the kernel modifies the VIDC list in order to apply the *TV setting, but it’s probably something that’s better done inside the driver. E.g. for the Raspberry Pi the overscan settings can be directly specified to the GPU, on OMAP they could be used to control the offset and scale of the desktop overlay, etc. Being able to configure these settings in the screen setup plugin would be nice.
The screen setup plugin could do with expanding to add support for driver-specific settings to be configured. E.g. overscan (as mentioned above), PAL/NTSC mode, compatibility options, red/blue swapping on Iyonix, etc.
Having a “configure” option in the display manager which launches the screen setup plugin for easy configuration of driver could also be nice.
Gamma handling needs revising; at the moment the GraphicsV palette calls handle both the palette and the gamma table, with no clear indication as to whether the gamma should apply to just the desktop overlay or the pointer (and any other overlays) as well.
Splitting per-head gamma handling into a separate call would be best, along with potentially allowing gamma to be specified on a per-overlay basis, with the palette calls only used to set the palette.
At the moment there’s no way of turning off a display once an OS/program has finished with it. The ClaimOS and ReleaseOS calls will help with this to a certain extent, but for situations where third party software is using a display separate calls to control power will be required.
Related to the above, an API is required to allow heads to be claimed by third-party software. Each head will have three states of ownership:
This system allows programs to coexist with the VDU much as they do now. Programs can use the standard OS APIs to change the screen mode, or they can claim ownership of the default head and set everything manually. If the program exits then the desktop will reclaim the head & overlays for the system, resetting the right WIMP mode.
It would also be desirable to have an API to allow for full control over whether a head has a desktop overlay and mouse pointer overlay assigned to it by the driver. For example a Geminus-like app which sets up a multiple display system would want desktop and pointer overlays on all the heads which it uses, using the existing GraphicsV calls to interact with them. But a movie player performing full-screen playback might only be interested in having a YUV overlay, accessed via the new overlay API.
Improve OS_ScreenMode 68 or implement a new call (direct GraphicsV calls?) to allow more information about the driver to be queried. Useful information to make available includes:
A call (OS_SpriteOp? OS_ScreenMode?) to check whether screen output is currently redirected to a sprite (and if so, where) would also be beneficial.
Consider how best to handle third-party (i.e. softloaded) extensions which provide additional functionality. E.g. a Raspberry Pi display which can be driven by the builtin driver, but has extra functionality (brightness, gamma, power) which requires custom code. Where GraphicsV APIs exist for controlling these features, it would be best if the display utility driver was able to provide implementations of those calls. So we need to try and make sure the APIs are designed in ways which allow utility drivers to easily implement them, without disturbing the functions offered by the builtin driver.
v1.00 – 31-Jan-2010
v2.00 – 28-Mar-2010
v2.01 04-Jul-2012
v2.02 24-Aug-2012
v2.03 21-Nov-2012
v3.00 26-Jan-2014
v3.10 02-Mar-2014
v3.20 10-Mar-2014
v3.30 25-Jul-2014
v3.40 09-Dec-2016
v3.41 31-Jan-2021