From 437d7f4b46f89e411c015e5673e3365cd3402418 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Tue, 16 Jul 2019 11:37:33 +0800 Subject: [PATCH] finish the doc --- Writing-DRI-Engine-Driver-for-Your-GPU.md | 214 ++++++++++++++++++++-- 1 file changed, 200 insertions(+), 14 deletions(-) diff --git a/Writing-DRI-Engine-Driver-for-Your-GPU.md b/Writing-DRI-Engine-Driver-for-Your-GPU.md index 6d694d0..6ebc41f 100644 --- a/Writing-DRI-Engine-Driver-for-Your-GPU.md +++ b/Writing-DRI-Engine-Driver-for-Your-GPU.md @@ -50,7 +50,7 @@ There are two configure options related to the `dri` engine: available on Linux, and you need to install the `libdrm` 2.4 or later first. * `--with-targetname=external`. When you configure MiniGUI with this - option. MiniGUI will use the external function `__dri_ex_driver_get` + option, MiniGUI will use the external function `__dri_ex_driver_get` to initialize the DRI driver. If you do not implement this function, the link will fail. @@ -67,23 +67,198 @@ pixelformat=XR24 device=/dev/dri/card0 ``` -You can use the key `dri.device` to specify your DRI device. +Note that the `defaultmode` and `dpi` keys are standard keys for +a NEWGAL engine. These two keys define the screen resolution for +MiniGUI. -You can use the key `dri.pixelformat` to specify the DRM pixel format for the -screen. We use DRM fourcc code to defined the pixel format of the screen -surface. For more information, please see `` header file. -Note that only 8/16/24/32 bpp RGB formats are supported. For example, `XR24` -means `X8R8G8B8` pixel format. +For `dri` engine, you can use the key `dri.device` to specify +your DRI device. Generally, it is `/dev/dri/card0`. + +You can use the key `dri.pixelformat` to specify the DRM pixel format +of the screen. We use libdrm's fourcc code to defined the pixel format +of the screen surface in MiniGUI run-time configuration. For example, +`XR24` means `X8R8G8B8` pixel format, and `AR32` means `A8R8G8B8` pixel +format. + +For more information, please see `` header file. +Note that only 8/16/24/32 bpp RGB formats are supported. ### Implement DRI driver -The header file `` defines the operators (a set of -callback functions) you need to implement for your GPU externally. +The header file `` defines the external sutbs and +the driver operators (a set of callback functions) you need to implement +for your GPU externally. + +First, you need to implement the following external stub: + + DriDriverOps* __dri_ex_driver_get (const char* driver_name); + +This function takes an argument `driver_name` and returns NULL or +a valid pointer of `DriDriverOps` to MiniGUI. The argument `driver_name` +gives the driver name determined by libdrm. Generally, it is the model +or number of your GPU. For example, for Intel i915 GPU, the driver name +will be `i915`. The `__dri_ex_driver_get` can returns different +`DriDriverOps` to MiniGUI according to the driver name. In this way, +your implementation can support multiple GPUs. + +If the external stub returns NULL, MiniGUI will use the dumb frame buffer +instead. + +The `DriDriverOps` is a struct type consisted by a set of operators +(callbacks): + + /** + * The struct type defines the operators for a DRI driver. + */ + typedef struct _DriDriverOps { + /** + * This operator creates the DriDriver object. + * + * \note The driver must implement this operator. + */ + DriDriver* (*create_driver) (int device_fd); + + /** + * This operator destroies the DriDriver object. + * + * \note The driver must implement this operator. + */ + void (*destroy_driver) (DriDriver *driver); + + /** + * This operator flushs the batch buffer of the driver or the hardware cache. + * + * \note This operator can be NULL. + */ + void (* flush_driver) (DriDriver *driver); + + /** + * This operator creates a buffer with the specified pixel format, + * width, and height. If succeed, a valid (not zero) buffer identifier + * and the picth (row stride in bytes) will be returned. + * If failed, it returns 0. + * + * \note The driver must implement this operator. + */ + uint32_t (* create_buffer) (DriDriver *driver, + uint32_t drm_format, + unsigned int width, unsigned int height, + unsigned int *pitch); + + BOOL (* fetch_buffer) (DriDriver *driver, + uint32_t buffer_id, + unsigned int *width, unsigned int *height, + unsigned int *pitch); + + /** + * This operator maps the buffer into the current process's virtual memory + * space, and returns the virtual address. If failed, it returns NULL. + * + * \note The driver must implement this operator. + */ + DriSurfaceBuffer* (* map_buffer) (DriDriver *driver, + uint32_t buffer_id); + + /** + * This operator un-maps a buffer. + * + * \note The driver must implement this operator. + */ + void (* unmap_buffer) (DriDriver *driver, DriSurfaceBuffer* buffer); + + /** + * This operator destroies a buffer. + * + * \note The driver must implement this operator. + */ + void (* destroy_buffer) (DriDriver *driver, uint32_t buffer_id); + + /** + * This operator clears the specific rectangle area of a buffer + * with the specific pixel value. If succeed, it returns 0. + * + * \note If this operator is set as NULL, the driver does not support + * hardware accelerated clear operation. + */ + int (* clear_buffer) (DriDriver *driver, + DriSurfaceBuffer* dst_buf, const GAL_Rect* rc, uint32_t pixel_value); + + /** + * This operator checks whether a hardware accelerated blit + * can be done between the source buffer and the destination buffer. + * If succeed, it returns 0. + * + * \note If this operator is set as NULL, it will be supposed that + * the driver does not support any hardware accelerated blit operation. + */ + int (* check_blit) (DriDriver *driver, + DriSurfaceBuffer* src_buf, DriSurfaceBuffer* dst_buf); + + /** + * This operator copies bits from a source buffer to a destination buffer. + * + * \note If this operator is set as NULL, the driver does not support + * hardware accelerated copy blit. + */ + int (* copy_blit) (DriDriver *driver, + DriSurfaceBuffer* src_buf, const GAL_Rect* src_rc, + DriSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, + enum DriColorLogicOp logic_op); + + /** + * This operator blits pixles from a source buffer with the source alpha value + * specified to a destination buffer. + * + * \note If this operator is set as NULL, the driver does not support + * hardware accelerated blit with alpha. + */ + int (* alpha_blit) (DriDriver *driver, + DriSurfaceBuffer* src_buf, const GAL_Rect* src_rc, + DriSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, uint8_t alpha); + + /** + * This operator blits pixles from a source buffer to a destination buffer, + * but skipping the pixel value specified by \a color_key. + * + * \note If this operator is set as NULL, the driver does not support + * hardware accelerated blit with color key. + */ + int (* key_blit) (DriDriver *driver, + DriSurfaceBuffer* src_buf, const GAL_Rect* src_rc, + DriSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, uint32_t color_key); + + /** + * This operator blits pixles from a source buffer with the source alpha value + * specified to a destination buffer, but skipping the pixel value specified. + * + * \note If this operator is set as NULL, the driver does not support + * hardware accelerated blit with alpha and color key. + */ + int (* alpha_key_blit) (DriDriver *driver, + DriSurfaceBuffer* src_buf, const GAL_Rect* src_rc, + DriSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, + uint8_t alpha, uint32_t color_key); + + } DriDriverOps; + +If the external stub `__dri_ex_driver_get` returns a valid pointer +of `DriDriverOps`, MiniGUI will call the operator `create_driver` +to initialize the DRI driver. The operator will return a pointer +to the type of `DriDriver`. All other operators of `DriDriverOps` +need this pointer as the context of your DRI driver. + +Note that MiniGUI does not defined the detailed structure of +`DriDriver`, it is up to your implementation: + + /** + * The struct type represents the DRI sub driver. + * The concrete struct should be defined by the driver. + */ + struct _DriDriver; + typedef struct _DriDriver DriDriver; + +For other operators, please see the comments above. -To exploit the GPU's accelerated rendering capabilities, a MiniGUI app -can use `cairo` and/or `OpenGL ES` to assist in rendering 2D/3D graphics -when using the `dri` engine. We will provide some samples in `mg-tests` -or `mg-samples` for this purpose. ### Restrictions @@ -98,8 +273,19 @@ need this privilege when you use the future `dri` engine. ## Example -As an example, we implement the sub driver for `i915` graphics chard +As an example, we implement the DRI driver for `i915` graphics chard in `mg-tests/dri-engine/`. Please refer to `mg-tests` repository: https://github.com/VincentWei/mg-tests/tree/master/dri-engine +## Future Features + +In the near future, the MiniGUI team will: + +* Enhance `dri` engine to support MiniGUI-Processes run-time mode. +* Implement the MiniGUI back-end of `cairo` and MiniGUI EGL for OpenGL, + OpenGL ES, and OpenVG, in order to fully exploit the GPU's 2D/3D + accelerated rendering capabilities. + +We will provide some samples in `mg-tests` or `mg-samples` for this purpose. +