Showing changes from revision #11 to #12:
Added | Removed | Changed
Details of new OS_ScreenMode calls are given in each individual section of the document.
New reason codes are numbered from 256+, 64+, to avoid clashing with ROL’s allocations which are numbered from 255 down.
The current GraphicsV API specifies that the top byte of R4 is used to specify the display number, with 0 being the ‘default’. However, no methods are defined (or implemented) for enumerating the list of available displays, notifying the system of display addition/removal, etc.
To rectify this, the following changes are proposed:
Display drivers are required to register themselves with the system via new OS_ScreenMode calls. This allows the OS to assign them driver IDs, and to let the OS know once the driver is ready for use.
In: The R0 pointer = overlay reason is code, set R1 by = one flags of (reserved, a sbz) number of routes:
Out: R0 = driver number
Call this from the foreground before claiming GraphicsV in order to determine which driver number you should respond to.
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.
In: Internally R0 the = kernel reason buffers code, the R1 32×32×2bpp = pointer driver images number and allows drivers to reference the buffered data directly. This is favourable for theVIDC 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.
Call this from the foreground once GraphicsV is claimed and the driver is ready to respond to requests from the OS. The OS will then query the driver to determine its capabilities, set the initial mode, etc.
In: R0 = reason code, R1 = driver number
Call this from the foreground when your driver is shutting down. During the call the driver may receive GraphicsV calls, which it should respond to as normal, but once the call has completed the driver shouldn’t receive any more calls.
A new feature flag will be required to allow drivers to indicate that they use the new pointer APi.
In: R0 = reason code, R1 = driver number
Call this from the foreground once your driver has released its claim on GraphicsV (or has otherwise stopped responding to requests). Splitting deregistration into a two-stage process ensures there won’t be any issues with driver numbers being reused if another driver tries to register itself after your driver has stopped but before your driver has released itself from GraphicsV.
Entry | |
---|---|
R0 | Shape number (0-3) |
R1 | Pointer to request block |
R4 | Reason code, driver number, etc. |
Exit | |
---|---|
- | Request block updated as appropriate |
The This primary call aim will of allow this change is to provide support for the features caller to query a driver’s level of the OMAP3 display subsystem. Thus, the new GraphicsV must support multiple for hardware a overlays, given each pointer with image. differing It restrictions operates on available a buffer request formats, block and with provide the ability following for format: programs to alter the display order of the overlays (where the hardware supports it)
To add support for hardware overlays, the following changes are proposed:
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 easlier 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:
GraphicsV already has some support for this via call 15. However that call only allows one head to be active at once; what’s needed instead is a way of supporting multiple active heads at once.
Proposal: Update GraphicsV and other OS components to allow a driver to have multiple heads active at once.
All existing GraphicsV calls will be updated to accept a head number in bits 16-23 of R4, with the exception of GraphicsV 15 (select head), which will become obsolete. Additionally, some new calls are needed:
Most, A if call not to all read of the above, number is capable of being available covered heads, by and the any settings other table driver-global described features. in the Display Capabilities & Configuration section.
A call to read the features of an individual head. In particular, it’s expected that it will need to return a bitmask indicating which other heads cannot be active at the same time as this head. For example, the Pandora TV-out cable offers S-Video and Composite as two separate connectors (and therefore separate heads from the user’s perspective), but it’s impossible to use both at once.
This call should also return a localised string containing the name of the head, suitable for display to the user, e.g. in the display manager. A head ID suitable for use in configuration files may also be desireable, however it’s expected that simply using the head number will be sufficient (as the head numbers should remain stable, at least until the user swaps the video card for another)
Both heads and overlays have ownership states. There are three different states of ownership:
The OS will issue this call when it begins to use a head for the VDU driver. The driver should use this call as a hint that it should give this head preferential treatment over other heads, e.g. ensuring a hardware cursor overlay is available.
The counterpart to ClaimOS, this call will be issued when the OS stops using a head.
The display manager and screen setup plugin will need updating to allow selection of the head to use. Rather than end up with two new drop downs (one for driver, one for head) it’ll probably make sense to combine them into one list.
Similar to with multiple driver support, consideration will be needed for how the default selection is stored in CMOS.
As most machines will be able to support multiple heads out of the box, display detection support will be required in order to ensure the OS picks the right head on startup.
Once multiple head support is implemented it’s worth considering implementing a Geminus-style app to allow for multiple monitor use within the desktop. There are, broadly speaking, four ways of providing multiple monitor support, each with differing level of implementation complexity:
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 monitor 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 desireable 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 desireable 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 desireable 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 desireable.
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.
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 desireable 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
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.
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.
It’s recommended that the GraphicsV 3 (set interlace) be deprecated, and that interlace only be specified via the flags in the VIDC list during mode changes. See this post for related discussion.
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.
GraphicsV 14 (IIC op) may need revising to make it clear how to access the extra banks of EDID that are present in some devices. If GraphcisV 14 is seen as a direct IIC interface then it will require the caller to manually program the bank prior to reading the EDID. However this could cause problems in threaded environments, as unlike OS_IICOp there’s no way of performing a repeated-start transfer to keep the bus locked for the duration of the operation.
Additionally the current implementation in BCMVideo doesn’t emulate the bank address register and instead allows the full > 256 bytes of data to be read from the main EDID IIC address.
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 overlays and set everything manually. If the program exits then the desktop will reclaim the head & overlays for the system, resetting the rightWIMP mode. Additionally, the inability of one program to reclaim an overlay that is owned by another allows for the safe implementation of media players and the like where moreYUV overlays may be requested than actually exist.
It would also be desireable 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 monitor 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.
If a user program wishes to do more than use the basic OS_ScreenMode interface that exists now, then it must also register itself with the system via a new OS_ScreenMode reason code. Upon registration the program will provide a pointer to a callback function that will be called upon certain important events (e.g. the system reclaiming a head or overlay that is owned by the program). Upon registration the program will also provide a list of understood property IDs (see the Display Capabilities & Configuration section); this will allow drivers to make ‘best guess’ choices for configuration values that the program does not provide or understand. In return for the registration request, the system will return to the program a unique ID that allows the system to identify the program. The program uses this ID when it wants to claim or relinquish ownership over resources.
(Further API details are TBD)
(Further API details are TBD)
There are many restrictions which govern how the different features of the OMAP3 display controller can be used. For example, the display timings affect the range of supported overlay scales; the colour format affects whether rotation is supported; scaling is only available with certain transparency methods; the colour phase rotation matrix is not available for TV-out; the limited number of transparency modes/overlay display orders places restrictions on the system if you want a YUV overlay to appear ‘under’ the desktop (i.e. so menus/windows and the mouse can appear ontop of it); PLL restrictions mean that the system isn’t capable of generating every pixel rate that lies between the min & max value; it may make sense to restrict configurations that use excessive memory bandwidth (e.g. having three fullscreen 32bpp overlays utilising transparency), to utilise hardware display rotation the driver will have to exert tight control over VRAM assignment, etc. Although creating an API that allows these restrictions (and any others that might apply to other hardware) to be communicated to programs is likely impossible, we can at the least strive for an API that:
As an attempt to satisfy the above criteria, all the configuration values of a driver will be contained within a table. Each column represents an entity within the driver (a head or an overlay), and each row represents a property. The values in the cells represent the configured values within the driver. By passing tables back and forth between programs and drivers, it is possible for programs to safely alter the configuration of the driver, to receive feedback about the driver’s current configuration, and to receive feedback about which configuration values are invalid.
Ordinarily the only rows that will be present in a settings table will be those that the program indicated to the system that it understood upon registration (via OS_ScreenMode X1). How to handle columns (i.e. whether all columns must always be present, or whether they are sometimes omitted) is TBD.
To use these new APIs, programs must first register themselves (see above)
New calls:
ID | Name | Description |
---|---|---|
1 | Enable | For heads, a bool indicating whether the head is enabled. |
For overlays, a bitmask indicating which heads the overlay is enabled on. | ||
2 | Head configuration | An enum indicating the head configuration in use. Each of the possible values is associated with a human-readable string, allowing the user to select the appropriate configuration (e.g. SVideo or Composite for TV-out) |
3 | X, Y | Two signed ints giving the coordinates of the head/overlay within ‘overlayspace’ |
4 | Width, height | Two unsigned ints giving the size of the head/overlay in pixels |
5 | Scaled size | Two signed ints giving the scaled size of the head/overlay in pixels. Zero has the special meaning of 1:1 scaling. Negative values allow for flipping of the image. |
6 | Rotation | Some value indicating the rotation to be applied to the head/overlay. |
7 | Colour phase rotation matrix | A 4×4 matrix that transforms the RGBA values of the head/overlay pixels |
8 | Transparency mode | An enum indicating the transparency mode in use by the head/overlay |
9 | Transparency colour key | Encoded pixel value that is treated as the transparent colour for the transparency colour key transparency method |
10 | Alpha | 0-255 value indicating global alpha of overlay |
11 | YUV matrix | A 4×3 matrix that transforms YUV values to RGB values |
12 | Display timings | A set of mode timings for the head (minus the display size, which is specified separately) |
13 | DMA settings | A set of DMA settings for an overlay. VIDC-style DMA init, base, and limit, along with vduinit (introduced by GraphicsV), and a value describing the number of bytes between each scanline (to allow for non-contiguous buffer formats that are required to make multi-monitor setups easy) |
14 | Overlay ordering | For heads, an enum indicating which overlay ordering is in use. |
For overlays, a notional Z value indicating how the overlays are layered ontop of each other. | ||
(The intention is that each driver will only one of the two ordering methods to be used at a time) | ||
15 | Palette mode | A bool indicating whether the overlay palette is fixed or flexible |
16 | Gamma mode | A bool indicating whether the head/overlay gamma table is fixed or flexible |
17 | Test card display | A bool indicating whether the head should display the built in ‘test card’ image, if any (e.g. TV-out colour bars on OMAP) |
18 | Background colour | A colour value giving the background colour used by the head (when no overlay is visible for a given pixel) |
19 | Border colour | A colour value giving the border colour used by the head |
The cursor overlay is set by one of a number of routes
These all ultimately call GraphicsV. A problem at present is that the sprite operations clip the shape to 32×32 pixels, so in an EY0 mode the 11×22 default mouse (sprite ptr_default) gets scaled to 22×44 and then the bottom 12 pixels are cropped.
A review of increasing the Y limit to 64 pixels may resolve this problem. Existing drivers to consider
So SpriteExtend (which implements OS_SpriteOp 36) may need to query GraphicsV to find where to clip, or change its box to 64×64 and let the GraphicsV driver do the clipping.
Care would be needed when transitioning the cursor between screens if, for example, one video driver had a different cursor ability to the other (eg. two PCI different cards).
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