Allocation module
You can use the WFD driver or a separate allocator module to handle the allocation functionality. If both are available, Screen uses the allocator module. If neither of the allocations method are provided, Screen won't start.
The WFD driver can be an allocator if it defines the WFD_QNX_egl_images extension, which must provide the wfdDestroyWFDEGLImagesQNX() and wfdCreateWFDEGLImagesQNX() functions. The memory returns in the form of a win_image_t structure, which Screen server then wraps with a libmemobj object.
The allocator module is configured with the alloc-config parameter
under the globals section of the configuration file. Screen server
loads (using dlopen()) the allocation module that is specified in the
configuration file, graphics.conf. Based on the interface used by
the allocation module, the returned memory will be in a form of a
libscrmem object with encapsulated
libmemobj object or as a win_image_t structure,
which Screen server then wraps with a libmemobj object.
In Screen server, all graphics buffer memory is encapsulated in a gbuf structure and all graphics buffer memory allocation requests have to go through the Graphics Buffer Management.

Functionality
The allocation module is responsible for the following:
- Creating buffers
-
The allocation module creates a buffer based on the size, pixel format and usage that is specified.
The usage of the buffer is particularly important information for the allocation module to have. This usage can dictate how and where the allocation module allocates the buffer (e.g., from a specific memory pool and/or if the memory must be in a physically contiguous region).
- Destroying buffers
- The allocation module frees the memory that was allocated.
- Importing and detaching external images specified as win_image_t
- This is an optional functionality that enables Screen to import and attach then detach external provided graphics memory.
Interfaces
The complete allocator module interface is described in screen/alloc.h. The allocator module can be designed to either return allocated memory specified as a scrmem object (refer to the libscrmem library for specification) or as a win_image_t structure (defined in screen/iomsg.h).
For details on import_image() and detach_images(), refer to screen/alloc.h.
The scrmem-based allocator
Screen expects the create_scrmem() function to be defined by the allocation module:
int (*create_scrmem)( int width,
int height,
int format,
int usage,
size_t count,
struct scrmem **scrmem );
- width
- The width of the image buffer, in pixels.
- height
- The height of the image buffer, in pixels.
- format
- A 32-bit integer, with lower 16-bit representing enum of pixel formats defined in screen.h, and higher 16-bit representing platform-specific variant of the pixel format, if one present.
- usage
- A bitmask indicating the intended usage for the graphics buffer. Available values are defined in screen.h.
- count
- The number of buffers to create.
- scrmem
- A pointer to the array libscrmem objects (each buffer has its own scrmem object associated with it), which is returned to Graphics Buffer Management
The destructor for this memory is specified during scrmem creation; refer to the libscrmem description for additional information. The destructor definition comes from the allocate module and not the caller. When the graphics buffer is no longer required, the Graphics Buffer Management unmaps and deallocates the corresponding the gbuf object (i.e., when it's no longer used by another other process or thread).
Interface logic
- Determine the size of the buffer based on requested height, width, usage and format
- Determine appropriate memobj attributes, such as if the memory should be typed, physical contiguous, have special cache flags.
-
For each buffer:
- If memory will be allocated by the libmemobj,
create memobj with attributes (from step 2). If
libmemobj needs to wrap memory:
allocate/obtain required memory and either provide a shared-memory
FD or vaddr to the libmemobj for wrapping. If
libmemobj handle is wrapping an already
allocated memory, then ensure that memory can be freed when it is no
longer needed (
memobjdestructor can be used for this cleanup). - Allocate and fill the win_image_t structure.
- Create a scrmem object with a memobj handle (from step 3a) and a win_image_t structure (from step 3b).
- Associate an appropriate destructor for the scrmem object. The destructor is part of the allocator design; it's responsible for cleaning up memory after the scrmem object is no longer required. At the very least, the destructor should free memory used by the win_image_t structure (allocated in step 3b) and close the memobj (from step 3a).
- If memory will be allocated by the libmemobj,
create memobj with attributes (from step 2). If
libmemobj needs to wrap memory:
allocate/obtain required memory and either provide a shared-memory
FD or vaddr to the libmemobj for wrapping. If
libmemobj handle is wrapping an already
allocated memory, then ensure that memory can be freed when it is no
longer needed (
The win_image_t-based allocator
In this interface, the returned images are described by the win_image_t structure. Screen server wraps this information into a libmemobj object before encapsulating it with gbuf information. This interface requires both the create_images() and destroy_images() functions:
create_images()
int (*create_images)( int width,
int height,
int format,
int usage,
size_t count,
struct win_image **images );
The parameters include:
- width
- The width of the image buffer, in pixels.
- height
- The height of the image buffer, in pixels.
- format
- A 32-bit integer, with the lower 16-bits representing an enum of pixel formats defined in screen.h and the higher 16-bits representing a platform-specific variant of the pixel format, if present.
- usage
- A bitmask indicating the intended usage for the graphics buffer. Available values are defined in screen.h.
- count
- The number of buffers to create.
- images
- A pointer used to return the allocated buffer.
destroy_images()
int (*destroy_images)( size_t count,
struct win_image **images );
The parameters include:
- count
- The number of buffers to destroy.
- images
- A pointer to the buffer location.
The WFD allocator
The WFD_QNX_egl_images extension
This interface is not a stand-alone module, but is a part of the display's WFD driver, which must support the WFD_QNX_egl_images extension. The Screen server uses the driver associated with the display (SCREEN_PROPERTY_DISPLAY) for the window, stream, or pixmap objects that will own the buffers.
As with the create_images() and destroy_images() interfaces, the returned object is of win_image_t type. The Screen server wraps this allocation into a libmemobj object before encapsulating it with gbuf information.
Both wfdCreateWFDEGLImagesQNX() and wfdDestroyWFDEGLImagesQNX() are required parts for this interface; refer to WF/wfdext.h for more information.
Information on buffer creation
- Special format bits
- The top 16 bits of the image format, if non-zero, indicate a
platform-specific variant of whatever format is associated with the lower 16
bits. For example, SCREEN_FORMAT_RGBA8888 has value 8; the
format
0x30008would have 8-bit R,G,B,A components, but might be tiled or have some other unusual memory layout. The caller can set these bits to request a specific format (if not possible, the call must fail). The allocator is also free to return a special format when not requested, if it does not conflict with the specified usage flags. In particular, the format must not be changed if READ and/or WRITE were requested. - Usage flags
The usage flags (SCREEN_USAGE_*) are described in the
Screen usage flag types
section of the Screen Graphics Subsystem Developer's Guide. A set of requested flags is passed to one of the above allocation APIs, which are expected to return an error if they don't support the combination of flags or failed to allocate for those purposes. On success, the returnedwin_image_tstructures are expected to have all requested usages, but may have additional ones added if the allocator determines the buffers are suitable for other uses.Note that these flags may be problematic for composition, including external composition, because there's no way to indicate which flags the compositor requires. Based on the expectations for the platform, the allocator may need to act as if certain flags are always present. For example, if the platform uses the
glescompositor, all buffers will need to be suitable for the GPU driver.- SCREEN_USAGE_DISPLAY
If requested, memory that is directly displayable by the WFD driver is required, and the allocation request must fail if it is not available. Screen always requests this for framebuffers.
If not requested, the allocator should add the bit if the allocated memory happens to be displayable. For example, some display controllers require physically contiguous memory, and the OS will often provide contiguous memory even when not specifically requested.
- SCREEN_USAGE_OVERLAY
- When requested, this implies SCREEN_USAGE_DISPLAY. An allocator shouldn't add this bit if not requested. It is intended more to change Screen's behavior than the allocator's.
- SCREEN_USAGE_READ, SCREEN_USAGE_WRITE
- If either of these usages are requested, the client expects to receive memory in the exact layout they requested. The allocator cannot substitute a special format in this case.
- SCREEN_USAGE_NATIVE
- This indicates the buffer must be usable as a source or destination (ideally both) for the platform's native blitter. If that is gles2blt, the flag is basically equivalent to SCREEN_USAGE_OPENGL_ES2.
- SCREEN_USAGE_VIDEO
- On some platforms, this implies suitability for a hardware video encoder/decoder.
- SCREEN_USAGE_CAPTURE
- This means the platform's video capture library can capture data into the buffer.
- SCREEN_USAGE_ROTATION
- If set, the allocator needs to fill
strides[1]in the returned win_image_t structures. Screen swaps the strides when rotating the buffer (the size, offset, and pointers remain the same).
- Typed memory pool
- On some hardware platforms, the memory has to be allocated from a
typed-memory pool. This pool can be specified with the
alloc-pool setting in the
globalssection of the graphics.conf file. - Rotation
- The support for rotation is hardware-depended. On the systems with rotation support, the allocation module will allocate addition memory for the buffer with SCREEN_USAGE_ROTATION. If WFD doesn't support rotation, the Screen server allocates additional graphic's buffers to perform rotation during composition.
Dependencies
Error handling
The allocation module returns an error code. Some possible error values are defined by POSIX while others are defined by QNX. Refer to the QNX OS C Library Reference for details. When the request for buffer creation is not successful, no memory is allocated; the allocation module cleans up any memory that it may have allocated in the process of processing this request.
Memory usage
The memory required by the module’s operation is considered negligible.
The allocation module is platform-dependent. Therefore, it can impose its own behavior (e.g., tiler memory). Memory allocation may be from specific areas of the system's RAM or external memory. Typically, the system's RAM is not usable to graphics hardware.
Some platforms require contiguous system RAM for buffer allocations. In this case, the allocation module may be sensitive to physical RAM fragmentation and chooses to pre-allocate RAM at startup to mitigate the issue of fragmentation.
Many GPUs operate in units that are larger than one pixel. For example, a 1x1 buffer must be rounded up to 4x4 or 128x128 based on your platform and hardware constraints. In this case, the allocation module must adjust input parameters to adhere to hardware constraints or to enable acceleration features. The allocation module may allocate a buffer that is a multiple of the requested size in the cases when the GPU requires an auxiliary buffer that's in a different format.
