From 5a6705d8bcbc0cc5fae6e13488e2c8d4a0ca50bf Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Sat, 21 Mar 2020 21:30:31 +0800 Subject: [PATCH] copy chagnes from 5.0.0 to enhance DRM engine to support PROCS runmode --- include/exstubs.h | 393 ++++-- include/gdi.h | 65 +- src/include/client.h | 23 +- src/include/newgal.h | 25 +- src/include/sharedres.h | 37 + src/kernel/init-lite.c | 24 +- src/newgal/drm/drmvideo.c | 2571 +++++++++++++++++++++---------------- src/newgal/drm/drmvideo.h | 28 +- src/newgal/newgal.c | 4 +- src/newgal/sysvideo.h | 4 +- src/newgal/video.c | 12 + src/newgdi/gdi.c | 66 +- src/server/request.c | 30 + 13 files changed, 2033 insertions(+), 1249 deletions(-) diff --git a/include/exstubs.h b/include/exstubs.h index d9924a7e..16c8648f 100644 --- a/include/exstubs.h +++ b/include/exstubs.h @@ -92,64 +92,226 @@ struct _DrmDriver; typedef struct _DrmDriver DrmDriver; /** - * The struct type represents the bufffer can be used by - * MiniGUI NEWGAL engine for hardware surface. + * The structure type represents the buffer can be used by + * MiniGUI NEWGAL DRM engine for a hardware surface. */ typedef struct _DrmSurfaceBuffer { - /** The prime fd of the buffer */ - int prime_fd; - /** The global name of the buffer */ - uint32_t name; /** The local handle of the buffer */ uint32_t handle; - /** The buffer identifier */ - uint32_t id; - /** The widht of the buffer */ - uint32_t width; - /** The height of the buffer */ - uint32_t height; - /** The pitch (row stride in bytes) of the buffer */ - uint32_t pitch; - /** The DRM format of the buffer */ - uint32_t drm_format; + /** + * The prime file descriptor of the buffer. + * It has a value >= 0 when this buffer has a prime file descriptor; + * otherwise it has the value -1; + */ + int prime_fd; + + /** + * The global name of the buffer. + * It has value > 0 when this buffer has a global name; + * otherwise it has the value 0; + */ + uint32_t name; + + /** + * The frame buffer identifier if the buffer has been added as a + * frame buffer to the system, otherwise it has the value 0. + */ + uint32_t fb_id; + + /** The DRM format of the buffer. */ + uint32_t drm_format; /** The bits per pixel */ uint32_t bpp:8; /** The bytes per pixel */ uint32_t cpp:8; - /** Is foreign surface */ - uint32_t foreign:1; + /** Is it a dumb buffer. Since 5.0.0. */ + uint32_t dumb:1; + /** Is it a scanout buffer. Since 5.0.0. */ + uint32_t scanout:1; + + /** The width of the buffer. */ + uint32_t width; + /** The height of the buffer. */ + uint32_t height; + /** The pitch (row stride in bytes) of the buffer. */ + uint32_t pitch; /** The whole size in bytes of the buffer */ - unsigned long size; - /** The mapped address of the buffer; NULL when the buffer is not mapped yet. */ - uint8_t* pixels; + size_t size; + + /** + * The offset from the buffer start to the real pixel data in bytes. + * It must be equal to or larger than the size of the buffer header. + * Since 5.0.0. + */ + off_t offset; + + /** + * The mapped address of the buffer; + * NULL when the buffer is not mapped yet. + * + * The address of the pixel data: + * uint8_t* pixels = this->buff + this->offset; + */ + uint8_t* buff; } DrmSurfaceBuffer; /** - * The color logic operations. + * The color blend mothed. + * + * See [Compositing and Blending Level 1](https://www.w3.org/TR/compositing-1/) */ -enum DrmColorLogicOp { - COLOR_LOGICOP_CLEAR = 0, - COLOR_LOGICOP_NOR = 1, - COLOR_LOGICOP_AND_INVERTED = 2, - COLOR_LOGICOP_COPY_INVERTED = 3, - COLOR_LOGICOP_AND_REVERSE = 4, - COLOR_LOGICOP_INVERT = 5, - COLOR_LOGICOP_XOR = 6, - COLOR_LOGICOP_NAND = 7, - COLOR_LOGICOP_AND = 8, - COLOR_LOGICOP_EQUIV = 9, - COLOR_LOGICOP_NOOP = 10, - COLOR_LOGICOP_OR_INVERTED = 11, - COLOR_LOGICOP_COPY = 12, - COLOR_LOGICOP_OR_REVERSE = 13, - COLOR_LOGICOP_OR = 14, - COLOR_LOGICOP_SET = 15 -}; +typedef enum { + /** Porter Duff rule: source over destination */ + COLOR_BLEND_PD_SRC_OVER = 0, + /** Porter Duff rule: destination over source */ + COLOR_BLEND_PD_DST_OVER, + /** Porter Duff rule: clear */ + COLOR_BLEND_PD_CLEAR, + /** Porter Duff rule: source */ + COLOR_BLEND_PD_SRC, + /** Porter Duff rule: destination */ + COLOR_BLEND_PD_DST, + /** Porter Duff rule: souorce in destination */ + COLOR_BLEND_PD_SRC_IN, + /** Porter Duff rule: destination in souorce */ + COLOR_BLEND_PD_DST_IN, + /** Porter Duff rule: source held out by destination */ + COLOR_BLEND_PD_SRC_OUT, + /** Porter Duff rule: destination held out by source */ + COLOR_BLEND_PD_DST_OUT, + /** Porter Duff rule: source atop destination */ + COLOR_BLEND_PD_SRC_ATOP, + /** Porter Duff rule: destination atop source */ + COLOR_BLEND_PD_DST_ATOP, + /** Porter Duff rule: source xor destination */ + COLOR_BLEND_PD_XOR, + /** Porter Duff rule: plus */ + COLOR_BLEND_PD_PLUS, + /** Porter Duff rule: modulate */ + COLOR_BLEND_PD_MODULATE, + + COLOR_BLEND_PD_FIRST = COLOR_BLEND_PD_SRC_OVER, + COLOR_BLEND_PD_LAST = COLOR_BLEND_PD_MODULATE, + + /** + * Separable blend mode: normal + * The blending formula simply selects the source color. + */ + COLOR_BLEND_SP_NORMAL, + /** + * Separable blend mode: multiply + * Darkens by multiplying colors: Sc·Dc. + */ + COLOR_BLEND_SP_MULTIPLY, + /** + * Separable blend mode: screen + * Complements product of complements: Sc + Dc - Sc·Dc. + */ + COLOR_BLEND_SP_SCREEN, + /** + * Separable blend mode: overlay + * Inverse of hard-light. + */ + COLOR_BLEND_SP_OVERLAY, + /** + * Separable blend mode: darken + * Minimum of colors: min(Sc, Dc). + */ + COLOR_BLEND_SP_DARKEN, + /** + * Separable blend mode: lighten + * Maximum of colors: max(Sc, Dc). + */ + COLOR_BLEND_SP_LIGHTEN, + /** + * Separable blend mode: color-dodge + * Brightens destination based on source. + */ + COLOR_BLEND_SP_COLOR_DODGE, + /** + * Separable blend mode: color-burn + * Darkens destination based on source. + */ + COLOR_BLEND_SP_COLOR_BURN, + /** + * Separable blend mode: hard-light + * Similar to effect of harsh spotlight. + */ + COLOR_BLEND_SP_HARD_LIGHT, + /** + * Separable blend mode: soft-light + * Similar to effect of soft spotlight. + */ + COLOR_BLEND_SP_SOFT_LIGHT, + /** + * Separable blend mode: difference + * Subtracts the darker from the lighter: Abs(Dc - Sc). + */ + COLOR_BLEND_SP_DIFFERENCE, + /** + * Separable blend mode: exclusion + * Similar to Difference but lower contrast. + */ + COLOR_BLEND_SP_EXCLUSION, + + COLOR_BLEND_SP_FIRST = COLOR_BLEND_SP_NORMAL, + COLOR_BLEND_SP_LAST = COLOR_BLEND_SP_EXCLUSION, + + /** + * Non-Separable blend mode: hue + * Creates a color with the hue of the source color and + * the saturation and luminosity of the backdrop color. + */ + COLOR_BLEND_NS_HUE, + /** + * Non-Separable blend mode: saturation + * Creates a color with the saturation of the source color and + * the hue and luminosity of the backdrop color. + */ + COLOR_BLEND_NS_SATURATION, + /** + * Non-Separable blend mode: color + * Creates a color with the hue and saturation of the source color + * and the luminosity of the backdrop color. + */ + COLOR_BLEND_NS_COLOR, + /** + * Non-Separable blend mode: luminosity + * Creates a color with the luminosity of the source color and + * the hue and saturation of the backdrop color. + */ + COLOR_BLEND_NS_LUMINOSITY, + + COLOR_BLEND_NS_FIRST = COLOR_BLEND_NS_HUE, + COLOR_BLEND_NS_LAST = COLOR_BLEND_NS_LUMINOSITY, +} ColorBlendMethod; /** - * The struct type defines the operations for a DRI driver. + * The color logical operations. + */ +typedef enum { + COLOR_LOGICOP_CLEAR = 0, + COLOR_LOGICOP_NOR, + COLOR_LOGICOP_AND_INVERTED, + COLOR_LOGICOP_COPY_INVERTED, + COLOR_LOGICOP_AND_REVERSE, + COLOR_LOGICOP_INVERT, + COLOR_LOGICOP_XOR, + COLOR_LOGICOP_NAND, + COLOR_LOGICOP_AND, + COLOR_LOGICOP_EQUIV, + COLOR_LOGICOP_NOOP0, + COLOR_LOGICOP_OR_INVERTED1, + COLOR_LOGICOP_COPY, + COLOR_LOGICOP_OR_REVERSE, + COLOR_LOGICOP_OR, + COLOR_LOGICOP_SET, +} ColorLogicalOp; + +/** + * The structure type defines the operations for a DRM driver. */ typedef struct _DrmDriverOps { /** @@ -160,81 +322,95 @@ typedef struct _DrmDriverOps { DrmDriver* (*create_driver) (int device_fd); /** - * This operation destroies the DrmDriver object. + * This operation destroys the DrmDriver object. * * \note The driver must implement this operation. */ void (*destroy_driver) (DrmDriver *driver); /** - * This operation flushs the batch buffer of the driver or the hardware cache. + * This operation flushes the batch buffer of the driver or + * the hardware cache. * * \note This operation can be NULL. */ void (* flush_driver) (DrmDriver *driver); /** - * This operation creates a buffer with the specified pixel format, - * width, and height. If succeed, a valid DrmSurfaceBuffer object will - * be returned; NULL on error. Note that the field of `pixels` of the - * DrmSurfaceBuffer object is NULL until the \a map_buffer was called. + * This operation creates a surface buffer with the specified pixel format, + * header size, width, and height. If succeed, a valid DrmSurfaceBuffer + * object will be returned; NULL on error. Note that the field of `buff` + * of the DrmSurfaceBuffer object is NULL until the \a map_buffer was called. * - * \note The driver must implement this operation. + * \note The driver must implement this operation and fill all fields of + * the new DrmSurfaceBuffer object. */ DrmSurfaceBuffer* (* create_buffer) (DrmDriver *driver, - uint32_t drm_format, - unsigned int width, unsigned int height); + uint32_t drm_format, uint32_t hdr_size, + uint32_t width, uint32_t height); /** - * This operation creates a buffer for the given handle - * with the specified pixel format, width, and height. If succeed, - * a valid DrmSurfaceBuffer object will be returned; NULL on error. + * This operation creates a buffer from a given and possibly foreign handle + * with the size of the buffer. If succeed, a valid DrmSurfaceBuffer object + * will be returned; NULL on error. * - * \note This operation can be NULL. + * \note This operation can be NULL. Note that the handle might was created + * by a foreign module. If implemented, the driver must + * fill the correct prime_fd, handle, name, and size fields of the new + * DrmSurfaceBuffer object. */ DrmSurfaceBuffer* (* create_buffer_from_handle) (DrmDriver *driver, - uint32_t handle, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, unsigned int pitch); + uint32_t handle, size_t size); /** * This operation creates a buffer for the given system global name - * with the specified pixel format, width, and height. If succeed, - * a valid DrmSurfaceBuffer object will be returned; NULL on error. + * If succeed, a valid DrmSurfaceBuffer object will be returned; + * NULL on error. * - * \note This operation can be NULL. + * \note This operation can be NULL. If implemented, the driver must + * fill the correct prime_fd, handle, name, and size fields of the new + * DrmSurfaceBuffer object. */ DrmSurfaceBuffer* (* create_buffer_from_name) (DrmDriver *driver, - uint32_t name, uint32_t drm_format, - unsigned int width, unsigned int height, unsigned int pitch); + uint32_t name); /** * This operation creates a buffer for the given PRIME file descriptor * with the specified pixel format, width, height, and pitch. If succeed, * a valid DrmSurfaceBuffer object will be returned; NULL on error. * - * \note This operation can be NULL. + * \note This operation can be NULL. If implemented, the driver must + * fill the correct prime_fd, handle, name, and size fields of the new + * DrmSurfaceBuffer object. */ DrmSurfaceBuffer* (* create_buffer_from_prime_fd) (DrmDriver *driver, - int prime_fd, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, unsigned int pitch); + int prime_fd, size_t size); /** * This operation 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 operation. + * When \a for_scanout is not zero, the buffer will be used for scan out + * frame buffer. + * + * \note The driver must implement this operation. The driver must + * set a valid value for buff field of the DrmSurfaceBuffer object + * on success. */ - uint8_t* (* map_buffer) (DrmDriver *driver, DrmSurfaceBuffer* buffer); + uint8_t* (* map_buffer) (DrmDriver *driver, DrmSurfaceBuffer* buffer, + int for_scanout); /** * This operation un-maps a buffer. * - * \note The driver must implement this operation. + * \note The driver must implement this operation. The driver must + * set NULL for buff field of the DrmSurfaceBuffer object + * on success. */ void (* unmap_buffer) (DrmDriver *driver, DrmSurfaceBuffer* buffer); /** - * This operation destroies a buffer. + * This operation destroys a buffer. * * \note The driver must implement this operation. */ @@ -256,7 +432,7 @@ typedef struct _DrmDriverOps { * If succeed, it returns 0. * * \note If this operation is set as NULL, it will be supposed that - * the driver does not support any hardware accelerated blit operation. + * the driver does not support any hardware accelerated blitting operation. */ int (* check_blit) (DrmDriver *driver, DrmSurfaceBuffer* src_buf, DrmSurfaceBuffer* dst_buf); @@ -265,51 +441,104 @@ typedef struct _DrmDriverOps { * This operation copies bits from a source buffer to a destination buffer. * * \note If this operation is set as NULL, the driver does not support - * hardware accelerated copy blit. + * hardware accelerated copy blitting. + * + * \note Currently, the logical operation is ignored. */ int (* copy_blit) (DrmDriver *driver, DrmSurfaceBuffer* src_buf, const GAL_Rect* src_rc, DrmSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, - enum DrmColorLogicOp logic_op); + ColorLogicalOp logic_op); /** - * This operation blits pixles from a source buffer with the source alpha value - * specified to a destination buffer. + * This operation blits pixles from a source buffer with the source alpha + * value specified to a destination buffer. * * \note If this operation is set as NULL, the driver does not support - * hardware accelerated blit with alpha. + * hardware accelerated blitting with alpha. */ int (* alpha_blit) (DrmDriver *driver, DrmSurfaceBuffer* src_buf, const GAL_Rect* src_rc, - DrmSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, uint8_t alpha); + DrmSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, + uint8_t alpha); /** * This operation blits pixles from a source buffer to a destination buffer, * but skipping the pixel value specified by \a color_key. * * \note If this operation is set as NULL, the driver does not support - * hardware accelerated blit with color key. + * hardware accelerated blitting with color key. */ int (* key_blit) (DrmDriver *driver, DrmSurfaceBuffer* src_buf, const GAL_Rect* src_rc, - DrmSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, uint32_t color_key); + DrmSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, + uint32_t color_key); /** - * This operation blits pixles from a source buffer with the source alpha value - * specified to a destination buffer, but skipping the pixel value specified. + * This operation 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 operation is set as NULL, the driver does not support - * hardware accelerated blit with alpha and color key. + * hardware accelerated blitting with alpha and color key. */ int (* alpha_key_blit) (DrmDriver *driver, DrmSurfaceBuffer* src_buf, const GAL_Rect* src_rc, DrmSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, uint8_t alpha, uint32_t color_key); + /** + * This operation blits pixles from a source buffer with the source alpha + * value of pixels to the destination buffer, and with the specified color + * compositing/blending method (\a ColorBlendMethod). + * + * \note If this operation is set as NULL, the driver does not support + * hardware accelerated blitting with alpha on basis per pixel. + * + * \note Currently, the color compositing/blending method is ignored. + */ + int (* alpha_pixel_blit) (DrmDriver *driver, + DrmSurfaceBuffer* src_buf, const GAL_Rect* src_rc, + DrmSurfaceBuffer* dst_buf, const GAL_Rect* dst_rc, + ColorBlendMethod blend_method); + } DrmDriverOps; -/** Implement this stub to return the DRI driver operations */ -DrmDriverOps* __drm_ex_driver_get (const char* driver_name, int device_fd); +/** The current version of DRM driver. */ +#define DRM_DRIVER_VERSION 1 + +/** + * Implement this stub to return the DRI driver operations + * + * This function takes three arguments and returns NULL or + * a valid pointer of DrmDriverOps to MiniGUI. + * + * This function can return different DrmDriverOps to MiniGUI according to + * the driver name and device file descriptor. In this way, your DRM engine + * driver implementation can support multiple GPUs. + * + * If the external stub returns NULL, MiniGUI will try to use the dumb + * frame buffer instead. + * + * \param driver_name This argument gives the driver name determined + * by MiniGUI. Generally, it is the kernel driver name for your GPU. + * For example, for Intel i915/i965 GPUs, the driver name will be `i915`. + * \param device_fd This argument gives the file descriptor of the + * opened DRI device. + * \param version A pointer to an integer which will contain the + * versionc of the DRM engine driver. + * + * \return NULL or a valid pointer to DrmDriverOps. + * + * \note We use the version control since 4.0.7. It will be intialized + * to zero by MiniGUI before calling this function. Because an old + * driver for MiniGUI 4.0.6 or earlier will not change the value, + * MiniGUI will deny to load the old driver. + * + * The constant \a DRM_DRIVER_VERSION defines the current version code. + */ +DrmDriverOps* __drm_ex_driver_get (const char* driver_name, int device_fd, + int* version); /** @} end of external_stubs_dri */ diff --git a/include/gdi.h b/include/gdi.h index 6d354a65..b06bdf6e 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -13734,14 +13734,18 @@ MG_EXPORT int drmGetDeviceFD (GHANDLE video); * THe struct type defines the DRM surface information. */ typedef struct _DrmSurfaceInfo { - /** The prime fd of the buffer object. */ - int prime_fd; - /** The global name of the buffer object. */ - uint32_t name; /** The local handle of the buffer object. */ uint32_t handle; - /** The buffer identifier. */ - uint32_t id; + /** The prime fd of the buffer object. If it was no exported as a global + buffer object, it has the value -1. */ + int prime_fd; + /** The global name of the buffer object. It has the value 0 when it was + not expored as global buffer object. */ + uint32_t name; + /** The frame buffer identifier. If the buffer was not added as + a frame buffer to the system, it has the value 0. */ + uint32_t fb_id; + /** The width of the surface. */ uint32_t width; /** The height of the surface. */ @@ -13751,7 +13755,9 @@ typedef struct _DrmSurfaceInfo { /** The DRM pixel format. */ uint32_t drm_format; /** Size in bytes of the buffer object. */ - unsigned long size; + size_t size; + /** The offset from the buffer start to the real pixel data. */ + off_t offset; } DrmSurfaceInfo; /** @@ -13773,15 +13779,24 @@ MG_EXPORT BOOL drmGetSurfaceInfo (GHANDLE video, HDC hdc, DrmSurfaceInfo* info); * \param video The video handle. * \param name The name handle of the DRM surface. * \param drm_format The DRM pixel format. + * \param offset The offset from the buffer start to the real pixel data. * \param width The width of the DRM surface. * \param height The height of the DRM surface. * \param pitch The pitch (row stride) of the DRM surface. * * \return The handle to the memory DC for success, HDC_INVALID for failure. */ -MG_EXPORT HDC drmCreateDCFromName (GHANDLE video, - uint32_t name, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch); +MG_EXPORT HDC drmCreateDCFromNameEx (GHANDLE video, + uint32_t name, uint32_t drm_format, off_t offset, + uint32_t width, uint32_t height, uint32_t pitch); + +static inline HDC drmCreateDCFromName (GHANDLE video, + uint32_t name, uint32_t drm_format, + uint32_t width, uint32_t height, uint32_t pitch) +{ + return drmCreateDCFromNameEx (video, + name, drm_format, 0, width, height, pitch); +} /** * This function creates a memory DC with a DRM surface which is created by @@ -13791,15 +13806,24 @@ MG_EXPORT HDC drmCreateDCFromName (GHANDLE video, * \param prime_fd The PRIME file descriptor. * \param size The size of the DRM surface in bytes. * \param drm_format The DRM pixel format. + * \param offset The offset from the buffer start to the real pixel data. * \param width The width of the DRM surface. * \param height The height of the DRM surface. * \param pitch The pitch (row stride) of the DRM surface. * * \return The handle to the memory DC for success, HDC_INVALID for failure. */ -MG_EXPORT HDC drmCreateDCFromPrimeFd (GHANDLE video, - int prime_fd, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch); +MG_EXPORT HDC drmCreateDCFromPrimeFdEx (GHANDLE video, + int prime_fd, size_t size, uint32_t drm_format, off_t offset, + uint32_t width, uint32_t height, uint32_t pitch); + +static inline HDC drmCreateDCFromPrimeFd (GHANDLE video, + int prime_fd, size_t size, uint32_t drm_format, + uint32_t width, uint32_t height, uint32_t pitch) +{ + return drmCreateDCFromPrimeFdEx (video, + prime_fd, size, drm_format, 0, width, height, pitch); +} /** * This function creates a memory DC with a DRM surface which is created by @@ -13809,15 +13833,24 @@ MG_EXPORT HDC drmCreateDCFromPrimeFd (GHANDLE video, * \param handle The handle of the DRM surface. * \param size The size of the DRM surface in bytes. * \param drm_format The DRM pixel format. + * \param offset The offset from the buffer start to the real pixel data. * \param width The width of the DRM surface. * \param height The height of the DRM surface. * \param pitch The pitch (row stride) of the DRM surface. * * \return The handle to the memory DC for success, HDC_INVALID for failure. */ -MG_EXPORT HDC drmCreateDCFromHandle (GHANDLE video, - uint32_t handle, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch); +MG_EXPORT HDC drmCreateDCFromHandleEx (GHANDLE video, + uint32_t handle, size_t size, uint32_t drm_format, off_t offset, + uint32_t width, uint32_t height, uint32_t pitch); + +static inline HDC drmCreateDCFromHandle (GHANDLE video, + uint32_t handle, size_t size, uint32_t drm_format, + uint32_t width, uint32_t height, uint32_t pitch) +{ + return drmCreateDCFromHandleEx (video, + handle, size, drm_format, 0, width, height, pitch); +} /** @} end of gdi_drm_fns */ diff --git a/src/include/client.h b/src/include/client.h index 92135993..39a85e60 100644 --- a/src/include/client.h +++ b/src/include/client.h @@ -95,12 +95,31 @@ #define REQID_GETIMEPOS 0x0019 #define REQID_SETIMEPOS 0x001A -#define REQID_COPYCURSOR 0x001B +#define REQID_COPYCURSOR 0x001B + +// Since 4.0.7: Authenticate client +#define REQID_AUTHCLIENT 0x001C + +// Since 4.0.7: Get shared surface +#define REQID_GETSHAREDSURFACE 0x001D + // for sharedfb schema + #define SYSSF_REAL_SCREEN "syssf-real-screen" /* - * XXX: To fellows who need to add a new REQID, please make sure your new ID _less_ than MAX_SYS_REQID (defined in /include/minigui.h). + * XXX: To fellows who need to add a new REQID, please make sure your + * new ID _less_ than MAX_SYS_REQID (defined in /include/minigui.h). */ +/* Since 4.0.7 */ +typedef struct _SharedSurfInfo { + uint32_t flags; // the flags of the surface + uint32_t width, height; + uint32_t pitch; + uint32_t name; // when use flink name + uint32_t drm_format; // DRM pixel format + size_t size; // whole size of the surface + off_t offset; // offset of pixel data +} SHAREDSURFINFO; typedef struct JoinLayerInfo { diff --git a/src/include/newgal.h b/src/include/newgal.h index 5e5688b2..d0b17f92 100644 --- a/src/include/newgal.h +++ b/src/include/newgal.h @@ -757,7 +757,7 @@ extern GAL_Surface* __gal_screen; #define GAL_BMask(surface) (surface->format->Bmask) #define GAL_AMask(surface) (surface->format->Amask) -extern int mg_InitGAL (void); +extern int mg_InitGAL (char* engine, char* mode); /* Since 4.0.0; suspend/resume video device, for switching virtual terminals */ extern int GAL_SuspendVideo(void); @@ -778,6 +778,29 @@ extern BYTE* gal_PutPixelKeyAlpha (GAL_Surface* dst, #define mg_TerminateGAL GAL_VideoQuit +#ifdef _MGRM_PROCESSES +/* Since 4.0.7: copy video information to the shared resource segment */ +BOOL GAL_CopyVideoInfoToSharedRes (void); +#endif /* _MGRM_PROCESSES */ + +#ifdef _MGGAL_DRM +/* functions implemented in DRM engine. */ +BOOL __drm_get_surface_info (GAL_Surface *surface, DrmSurfaceInfo* info); +int __drm_auth_client (int, uint32_t); + +GAL_Surface* __drm_create_surface_from_name (GHANDLE video, + uint32_t name, uint32_t drm_format, uint32_t pixels_off, + uint32_t width, uint32_t height, uint32_t pitch); + +GAL_Surface* __drm_create_surface_from_handle (GHANDLE video, + uint32_t handle, size_t size, uint32_t drm_format, uint32_t pixels_off, + uint32_t width, uint32_t height, uint32_t pitch); + +GAL_Surface* __drm_create_surface_from_prime_fd (GHANDLE video, + int prime_fd, size_t size, uint32_t drm_format, uint32_t pixels_off, + uint32_t width, uint32_t height, uint32_t pitch); +#endif /* defined _MGGAL_DRM */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/include/sharedres.h b/src/include/sharedres.h index 766f5f67..65e967f8 100644 --- a/src/include/sharedres.h +++ b/src/include/sharedres.h @@ -88,10 +88,30 @@ inline static key_t get_sem_key_for_layers (void) return (key_t)(IPC_KEY_BASE + 0x03); } +/* constants for engine name and video mode */ +#define LEN_SO_NAME 127 // name length of a shared object (library) +#define LEN_DEVICE_NAME 127 +#define LEN_EXDRIVER_NAME LEN_SO_NAME +#define LEN_ENGINE_NAME 23 +#define LEN_VIDEO_MODE 31 +#define LEN_MTYPE_NAME 23 +#define LEN_FOURCC_FORMAT 7 + typedef struct tagG_RES { int semid; int shmid; + /* information of NEWGAL engine; since 4.0.7 */ + char video_engine [LEN_ENGINE_NAME + 1]; + char video_mode [LEN_VIDEO_MODE + 1]; + char video_device [LEN_DEVICE_NAME + 1]; + int video_dpi, video_hres, video_vres, video_depth; + Uint32 video_rmask, video_gmask, video_bmask, video_amask; +#ifdef _MGGAL_DRM + char video_exdriver [LEN_EXDRIVER_NAME + 1]; + Uint32 video_drm_format; +#endif + int nr_layers; int semid_layer; @@ -150,6 +170,23 @@ typedef struct tagG_RES { } G_RES; typedef G_RES* PG_RES; +#define SHAREDRES_VIDEO_ENGINE (((PG_RES)mgSharedRes)->video_engine) +#define SHAREDRES_VIDEO_MODE (((PG_RES)mgSharedRes)->video_mode) +#define SHAREDRES_VIDEO_DEVICE (((PG_RES)mgSharedRes)->video_device) +#define SHAREDRES_VIDEO_DPI (((PG_RES)mgSharedRes)->video_dpi) +#define SHAREDRES_VIDEO_HRES (((PG_RES)mgSharedRes)->video_hres) +#define SHAREDRES_VIDEO_VRES (((PG_RES)mgSharedRes)->video_vres) +#define SHAREDRES_VIDEO_DEPTH (((PG_RES)mgSharedRes)->video_depth) +#define SHAREDRES_VIDEO_RMASK (((PG_RES)mgSharedRes)->video_rmask) +#define SHAREDRES_VIDEO_GMASK (((PG_RES)mgSharedRes)->video_gmask) +#define SHAREDRES_VIDEO_BMASK (((PG_RES)mgSharedRes)->video_bmask) +#define SHAREDRES_VIDEO_AMASK (((PG_RES)mgSharedRes)->video_amask) + +#ifdef _MGGAL_DRM +#define SHAREDRES_VIDEO_EXDRIVER (((PG_RES)mgSharedRes)->video_exdriver) +#define SHAREDRES_VIDEO_DRM_FORMAT (((PG_RES)mgSharedRes)->video_drm_format) +#endif + #define SHAREDRES_TIMER_COUNTER (((PG_RES)mgSharedRes)->timer_counter) #define SHAREDRES_TICK_ON_LOCKSEM (((PG_RES)mgSharedRes)->tick_on_locksem) #define SHAREDRES_TIMEOUT (((PG_RES)mgSharedRes)->timeout) diff --git a/src/kernel/init-lite.c b/src/kernel/init-lite.c index cc69ebee..90192007 100644 --- a/src/kernel/init-lite.c +++ b/src/kernel/init-lite.c @@ -108,6 +108,8 @@ void kernel_ShowCursorForGDI(BOOL fShow, void* pdc) int InitGUI (int argc, const char* agr[]) { + char engine [LEN_ENGINE_NAME + 1]; + char mode [LEN_VIDEO_MODE + 1]; int step = 1; __mg_quiting_stage = _MG_QUITING_STAGE_RUNNING; @@ -135,7 +137,7 @@ int InitGUI (int argc, const char* agr[]) step++; /* Init GAL engine. */ - switch (mg_InitGAL ()) { + switch (mg_InitGAL (engine, mode)) { case ERR_CONFIG_FILE: err_message (step, "Reading configuration failure!"); return step; @@ -302,6 +304,8 @@ static BOOL InstallSEGVHandler (void) int InitGUI (int argc, const char* agr[]) { + char engine [LEN_ENGINE_NAME + 1]; + char mode [LEN_VIDEO_MODE + 1]; int step = 1; __mg_quiting_stage = _MG_QUITING_STAGE_RUNNING; @@ -379,7 +383,7 @@ int InitGUI (int argc, const char* agr[]) #endif /* Init GAL engine. */ - switch (mg_InitGAL ()) { + switch (mg_InitGAL (engine, mode)) { case ERR_CONFIG_FILE: err_message (step, "Reading configuration failure!"); return step; @@ -444,6 +448,22 @@ int InitGUI (int argc, const char* agr[]) } atexit (kernel_UnloadSharedResource); SHAREDRES_TERMIOS = savedtermio; + + /* Since 4.0.7 + * Copy the video engine information to the shared resource segement + */ + strncpy (SHAREDRES_VIDEO_ENGINE, engine, LEN_ENGINE_NAME); + strncpy (SHAREDRES_VIDEO_MODE, mode, LEN_VIDEO_MODE); + SHAREDRES_VIDEO_DPI = __gal_screen->dpi; + SHAREDRES_VIDEO_HRES = __gal_screen->w; + SHAREDRES_VIDEO_VRES = __gal_screen->h; + SHAREDRES_VIDEO_DEPTH = __gal_screen->format->BitsPerPixel; + SHAREDRES_VIDEO_RMASK = __gal_screen->format->Rmask; + SHAREDRES_VIDEO_GMASK = __gal_screen->format->Gmask; + SHAREDRES_VIDEO_BMASK = __gal_screen->format->Bmask; + SHAREDRES_VIDEO_AMASK = __gal_screen->format->Amask; + + GAL_CopyVideoInfoToSharedRes(); } step++; diff --git a/src/newgal/drm/drmvideo.c b/src/newgal/drm/drmvideo.c index 99942edf..f1030a5b 100644 --- a/src/newgal/drm/drmvideo.c +++ b/src/newgal/drm/drmvideo.c @@ -15,7 +15,7 @@ * and Graphics User Interface (GUI) support system for embedded systems * and smart IoT devices. * - * Copyright (C) 2019, Beijing FMSoft Technologies Co., Ltd. + * Copyright (C) 2019 ~ 2020, Beijing FMSoft Technologies Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -67,9 +68,21 @@ #include "newgal.h" #include "exstubs.h" +#include "cursor.h" #include "pixels_c.h" #include "drmvideo.h" +#ifdef _MGRM_PROCESSES +#include "client.h" +#include "sharedres.h" +#endif + +#ifdef _MGRM_PROCESSES +/* we use shm_open for the shared shadow screen buffer among processes + under MiniGUI-Processes runtime mode and shared frame buffer schema. */ +#define SHMNAME_SHADOW_SCREEN_BUFFER "/minigui-procs-shadow-screen-buffer" +#endif /* defined _MGRM_PROCESSES */ + #define DRM_DRIVER_NAME "drm" /* DRM engine methods for both dumb buffer and acclerated buffers */ @@ -79,38 +92,712 @@ static int DRM_SetColors(_THIS, int firstcolor, int ncolors, GAL_Color *colors); static void DRM_VideoQuit(_THIS); static int DRM_Suspend(_THIS); static int DRM_Resume(_THIS); +#ifdef _MGRM_PROCESSES +static void DRM_CopyVideoInfoToSharedRes(_THIS); +#endif -/* DRM engine operators for dumb buffer */ -static GAL_Surface *DRM_SetVideoMode_Dumb(_THIS, GAL_Surface *current, +/* DRM engine methods for dumb buffer */ +static GAL_Surface *DRM_SetVideoMode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags); -static int DRM_AllocHWSurface_Dumb(_THIS, GAL_Surface *surface); -static void DRM_FreeHWSurface_Dumb(_THIS, GAL_Surface *surface); -/* DRM engine operators accelerated */ -static GAL_Surface *DRM_SetVideoMode_Accl(_THIS, GAL_Surface *current, - int width, int height, int bpp, Uint32 flags); +/* DRM engine methods accelerated */ static int DRM_AllocHWSurface_Accl(_THIS, GAL_Surface *surface); static void DRM_FreeHWSurface_Accl(_THIS, GAL_Surface *surface); static int DRM_CheckHWBlit_Accl(_THIS, GAL_Surface *src, GAL_Surface *dst); static int DRM_FillHWRect_Accl(_THIS, GAL_Surface *dst, GAL_Rect *rect, Uint32 color); -static void DRM_UpdateRects_Accl (_THIS, int numrects, GAL_Rect *rects); + +static void DRM_UpdateRects(_THIS, int numrects, GAL_Rect *rects); + static int DRM_SetHWColorKey_Accl(_THIS, GAL_Surface *surface, Uint32 key); static int DRM_SetHWAlpha_Accl(_THIS, GAL_Surface *surface, Uint8 value); +#ifdef _MGRM_PROCESSES +/* DRM engine methods for clients under sharedfb schema and MiniGUI-Processes */ +static GAL_Surface *DRM_SetVideoMode_Client(_THIS, GAL_Surface *current, + int width, int height, int bpp, Uint32 flags); +#endif /* defined _MGRM_PROCESSES */ + /* DRM driver bootstrap functions */ static int DRM_Available(void) { return drmAvailable(); } +/* format conversion helpers */ +static int drm_format_to_bpp(uint32_t drm_format, + int* bpp, int* cpp) +{ + switch (drm_format) { + case DRM_FORMAT_RGB332: + case DRM_FORMAT_BGR233: + *bpp = 8; + *cpp = 1; + break; + + case DRM_FORMAT_XRGB4444: + case DRM_FORMAT_XBGR4444: + case DRM_FORMAT_RGBX4444: + case DRM_FORMAT_BGRX4444: + case DRM_FORMAT_ARGB4444: + case DRM_FORMAT_ABGR4444: + case DRM_FORMAT_RGBA4444: + case DRM_FORMAT_BGRA4444: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XBGR1555: + case DRM_FORMAT_RGBX5551: + case DRM_FORMAT_BGRX5551: + case DRM_FORMAT_ARGB1555: + case DRM_FORMAT_ABGR1555: + case DRM_FORMAT_RGBA5551: + case DRM_FORMAT_BGRA5551: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + *bpp = 16; + *cpp = 2; + break; + + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + *bpp = 24; + *cpp = 3; + break; + + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_RGBX8888: + case DRM_FORMAT_BGRX8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_RGBA8888: + case DRM_FORMAT_BGRA8888: + *bpp = 32; + *cpp = 4; + break; + + default: + return -1; + } + + return 0; +} + +static inline uint32_t get_def_drm_format(int bpp) +{ + switch (bpp) { + case 32: + return DRM_FORMAT_XRGB8888; + case 24: + return DRM_FORMAT_RGB888; + case 16: + return DRM_FORMAT_RGB565; + case 8: + return DRM_FORMAT_RGB332; + default: + break; + } + + return DRM_FORMAT_RGB565; +} + +static uint32_t get_drm_format_from_etc(int* bpp) +{ + uint32_t format; + char fourcc[8] = {}; + +#ifdef _MGRM_PROCESSES + if (mgIsServer) { +#endif + if (GetMgEtcValue ("drm", "pixelformat", fourcc, 4) < 0) { + format = get_def_drm_format(*bpp); + } + else { + format = fourcc_code(fourcc[0], fourcc[1], fourcc[2], fourcc[3]); + } +#ifdef _MGRM_PROCESSES + } + else { + format = SHAREDRES_VIDEO_DRM_FORMAT; + } +#endif + + switch (format) { + case DRM_FORMAT_RGB332: + case DRM_FORMAT_BGR233: + *bpp = 8; + break; + + case DRM_FORMAT_XRGB4444: + case DRM_FORMAT_XBGR4444: + case DRM_FORMAT_RGBX4444: + case DRM_FORMAT_BGRX4444: + case DRM_FORMAT_ARGB4444: + case DRM_FORMAT_ABGR4444: + case DRM_FORMAT_RGBA4444: + case DRM_FORMAT_BGRA4444: + case DRM_FORMAT_XRGB1555: + case DRM_FORMAT_XBGR1555: + case DRM_FORMAT_RGBX5551: + case DRM_FORMAT_BGRX5551: + case DRM_FORMAT_ARGB1555: + case DRM_FORMAT_ABGR1555: + case DRM_FORMAT_RGBA5551: + case DRM_FORMAT_BGRA5551: + case DRM_FORMAT_RGB565: + case DRM_FORMAT_BGR565: + *bpp = 16; + break; + + case DRM_FORMAT_RGB888: + case DRM_FORMAT_BGR888: + *bpp = 24; + break; + + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_XBGR8888: + case DRM_FORMAT_RGBX8888: + case DRM_FORMAT_BGRX8888: + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_RGBA8888: + case DRM_FORMAT_BGRA8888: +#if 0 + case DRM_FORMAT_XRGB2101010: + case DRM_FORMAT_XBGR2101010: + case DRM_FORMAT_RGBX1010102: + case DRM_FORMAT_BGRX1010102: + case DRM_FORMAT_ARGB2101010: + case DRM_FORMAT_ABGR2101010: + case DRM_FORMAT_RGBA1010102: + case DRM_FORMAT_BGRA1010102: +#endif + *bpp = 32; + break; + default: + _ERR_PRINTF("NEWGAL>DRM: not supported pixel format: %s\n", + fourcc); + return 0; + break; + } + + return format; +} + +struct rgbamasks_drm_format_map { + uint32_t drm_format; + Uint32 Rmask, Gmask, Bmask, Amask; +}; + +static struct rgbamasks_drm_format_map _format_map_8bpp [] = { + { DRM_FORMAT_RGB332, 0xE0, 0x1C, 0x03, 0x00 }, + { DRM_FORMAT_BGR233, 0x0E, 0x38, 0xC0, 0x00 }, +}; + +static struct rgbamasks_drm_format_map _format_map_16bpp [] = { + { DRM_FORMAT_XRGB4444, 0x0F00, 0x00F0, 0x000F, 0x0000 }, + { DRM_FORMAT_XBGR4444, 0x000F, 0x00F0, 0x0F00, 0x0000 }, + { DRM_FORMAT_RGBX4444, 0xF000, 0x0F00, 0x00F0, 0x0000 }, + { DRM_FORMAT_BGRX4444, 0x00F0, 0x0F00, 0xF000, 0x0000 }, + { DRM_FORMAT_ARGB4444, 0x0F00, 0x00F0, 0x000F, 0xF000 }, + { DRM_FORMAT_ABGR4444, 0x000F, 0x00F0, 0x0F00, 0xF000 }, + { DRM_FORMAT_RGBA4444, 0xF000, 0x0F00, 0x00F0, 0x000F }, + { DRM_FORMAT_BGRA4444, 0x00F0, 0x0F00, 0xF000, 0x000F }, + { DRM_FORMAT_XRGB1555, 0x7C00, 0x03E0, 0x001F, 0x0000 }, + { DRM_FORMAT_XBGR1555, 0x001F, 0x03E0, 0x7C00, 0x0000 }, + { DRM_FORMAT_RGBX5551, 0xF800, 0x07C0, 0x003E, 0x0000 }, + { DRM_FORMAT_BGRX5551, 0x003E, 0x07C0, 0xF800, 0x0000 }, + { DRM_FORMAT_ARGB1555, 0x7C00, 0x03E0, 0x001F, 0x8000 }, + { DRM_FORMAT_ABGR1555, 0x001F, 0x03E0, 0x7C00, 0x8000 }, + { DRM_FORMAT_RGBA5551, 0xF800, 0x07C0, 0x003E, 0x0001 }, + { DRM_FORMAT_BGRA5551, 0x003E, 0x07C0, 0xF800, 0x0001 }, + { DRM_FORMAT_RGB565, 0xF800, 0x07E0, 0x001F, 0x0000 }, + { DRM_FORMAT_BGR565, 0x001F, 0x07E0, 0xF800, 0x0000 }, +}; + +static struct rgbamasks_drm_format_map _format_map_24bpp [] = { + { DRM_FORMAT_RGB888, 0xFF0000, 0x00FF00, 0x0000FF, 0x000000 }, + { DRM_FORMAT_BGR888, 0x0000FF, 0x00FF00, 0xFF0000, 0x000000 }, +}; + +static struct rgbamasks_drm_format_map _format_map_32bpp [] = { + { DRM_FORMAT_XRGB8888, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, + { DRM_FORMAT_XBGR8888, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }, + { DRM_FORMAT_RGBX8888, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, + { DRM_FORMAT_BGRX8888, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, + { DRM_FORMAT_ARGB8888, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, + { DRM_FORMAT_ABGR8888, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, + { DRM_FORMAT_RGBA8888, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, + { DRM_FORMAT_BGRA8888, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, +}; + +static uint32_t translate_gal_format(const GAL_PixelFormat *gal_format) +{ + struct rgbamasks_drm_format_map* map; + size_t i, n; + + switch (gal_format->BitsPerPixel) { + case 8: + map = _format_map_8bpp; + n = TABLESIZE(_format_map_8bpp); + break; + + case 16: + map = _format_map_16bpp; + n = TABLESIZE(_format_map_16bpp); + break; + + case 24: + map = _format_map_24bpp; + n = TABLESIZE(_format_map_24bpp); + break; + + case 32: + map = _format_map_32bpp; + n = TABLESIZE(_format_map_32bpp); + break; + + default: + return 0; + } + + for (i = 0; i < n; i++) { + if (gal_format->Rmask == map[i].Rmask && + gal_format->Gmask == map[i].Gmask && + gal_format->Bmask == map[i].Bmask && + gal_format->Amask == map[i].Amask) { + return map[i].drm_format; + } + } + + return 0; +} + +static int translate_drm_format(uint32_t drm_format, Uint32* RGBAmasks, + int* ret_cpp) +{ + int bpp = 0; + int cpp = 0; + + switch (drm_format) { + case DRM_FORMAT_RGB332: + RGBAmasks[0] = 0xE0; + RGBAmasks[1] = 0x1C; + RGBAmasks[2] = 0x03; + RGBAmasks[3] = 0x00; + bpp = 8; + cpp = 1; + break; + + case DRM_FORMAT_BGR233: + RGBAmasks[0] = 0x0E; + RGBAmasks[1] = 0x38; + RGBAmasks[2] = 0xC0; + RGBAmasks[3] = 0x00; + bpp = 8; + cpp = 1; + break; + + case DRM_FORMAT_XRGB4444: + RGBAmasks[0] = 0x0F00; + RGBAmasks[1] = 0x00F0; + RGBAmasks[2] = 0x000F; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_XBGR4444: + RGBAmasks[0] = 0x000F; + RGBAmasks[1] = 0x00F0; + RGBAmasks[2] = 0x0F00; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_RGBX4444: + RGBAmasks[0] = 0xF000; + RGBAmasks[1] = 0x0F00; + RGBAmasks[2] = 0x00F0; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_BGRX4444: + RGBAmasks[0] = 0x00F0; + RGBAmasks[1] = 0x0F00; + RGBAmasks[2] = 0xF000; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_ARGB4444: + RGBAmasks[0] = 0x0F00; + RGBAmasks[1] = 0x00F0; + RGBAmasks[2] = 0x000F; + RGBAmasks[3] = 0xF000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_ABGR4444: + RGBAmasks[0] = 0x000F; + RGBAmasks[1] = 0x00F0; + RGBAmasks[2] = 0x0F00; + RGBAmasks[3] = 0xF000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_RGBA4444: + RGBAmasks[0] = 0xF000; + RGBAmasks[1] = 0x0F00; + RGBAmasks[2] = 0x00F0; + RGBAmasks[3] = 0x000F; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_BGRA4444: + RGBAmasks[0] = 0x00F0; + RGBAmasks[1] = 0x0F00; + RGBAmasks[2] = 0xF000; + RGBAmasks[3] = 0x000F; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_XRGB1555: + RGBAmasks[0] = 0x7C00; + RGBAmasks[1] = 0x03E0; + RGBAmasks[2] = 0x001F; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_XBGR1555: + RGBAmasks[0] = 0x001F; + RGBAmasks[1] = 0x03E0; + RGBAmasks[2] = 0x7C00; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_RGBX5551: + RGBAmasks[0] = 0xF800; + RGBAmasks[1] = 0x07C0; + RGBAmasks[2] = 0x003E; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_BGRX5551: + RGBAmasks[0] = 0x003E; + RGBAmasks[1] = 0x07C0; + RGBAmasks[2] = 0xF800; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_ARGB1555: + RGBAmasks[0] = 0x7C00; + RGBAmasks[1] = 0x03E0; + RGBAmasks[2] = 0x001F; + RGBAmasks[3] = 0x8000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_ABGR1555: + RGBAmasks[0] = 0x001F; + RGBAmasks[1] = 0x03E0; + RGBAmasks[2] = 0x7C00; + RGBAmasks[3] = 0x8000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_RGBA5551: + RGBAmasks[0] = 0xF800; + RGBAmasks[1] = 0x07C0; + RGBAmasks[2] = 0x003E; + RGBAmasks[3] = 0x0001; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_BGRA5551: + RGBAmasks[0] = 0x003E; + RGBAmasks[1] = 0x07C0; + RGBAmasks[2] = 0xF800; + RGBAmasks[3] = 0x0001; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_RGB565: + RGBAmasks[0] = 0xF800; + RGBAmasks[1] = 0x07E0; + RGBAmasks[2] = 0x001F; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_BGR565: + RGBAmasks[0] = 0x001F; + RGBAmasks[1] = 0x07E0; + RGBAmasks[2] = 0xF800; + RGBAmasks[3] = 0x0000; + bpp = 16; + cpp = 2; + break; + + case DRM_FORMAT_RGB888: + RGBAmasks[0] = 0xFF0000; + RGBAmasks[1] = 0x00FF00; + RGBAmasks[2] = 0x0000FF; + RGBAmasks[3] = 0x000000; + bpp = 24; + cpp = 3; + break; + + case DRM_FORMAT_BGR888: + RGBAmasks[0] = 0x0000FF; + RGBAmasks[1] = 0x00FF00; + RGBAmasks[2] = 0xFF0000; + RGBAmasks[3] = 0x000000; + bpp = 24; + cpp = 3; + break; + + case DRM_FORMAT_XRGB8888: + RGBAmasks[0] = 0x00FF0000; + RGBAmasks[1] = 0x0000FF00; + RGBAmasks[2] = 0x000000FF; + RGBAmasks[3] = 0x00000000; + bpp = 32; + cpp = 4; + break; + + case DRM_FORMAT_XBGR8888: + RGBAmasks[0] = 0x000000FF; + RGBAmasks[1] = 0x0000FF00; + RGBAmasks[2] = 0x00FF0000; + RGBAmasks[3] = 0x00000000; + bpp = 32; + cpp = 4; + break; + + case DRM_FORMAT_RGBX8888: + RGBAmasks[0] = 0xFF000000; + RGBAmasks[1] = 0x00FF0000; + RGBAmasks[2] = 0x0000FF00; + RGBAmasks[3] = 0x00000000; + bpp = 32; + cpp = 4; + break; + + case DRM_FORMAT_BGRX8888: + RGBAmasks[0] = 0x0000FF00; + RGBAmasks[1] = 0x00FF0000; + RGBAmasks[2] = 0xFF000000; + RGBAmasks[3] = 0x00000000; + bpp = 32; + cpp = 4; + break; + + case DRM_FORMAT_ARGB8888: + RGBAmasks[0] = 0x00FF0000; + RGBAmasks[1] = 0x0000FF00; + RGBAmasks[2] = 0x000000FF; + RGBAmasks[3] = 0xFF000000; + bpp = 32; + cpp = 4; + break; + + case DRM_FORMAT_ABGR8888: + RGBAmasks[0] = 0x000000FF; + RGBAmasks[1] = 0x0000FF00; + RGBAmasks[2] = 0x00FF0000; + RGBAmasks[3] = 0xFF000000; + bpp = 32; + cpp = 4; + break; + + case DRM_FORMAT_RGBA8888: + RGBAmasks[0] = 0xFF000000; + RGBAmasks[1] = 0x00FF0000; + RGBAmasks[2] = 0x0000FF00; + RGBAmasks[3] = 0x000000FF; + bpp = 32; + cpp = 4; + break; + + case DRM_FORMAT_BGRA8888: + RGBAmasks[0] = 0x0000FF00; + RGBAmasks[1] = 0x00FF0000; + RGBAmasks[2] = 0xFF000000; + RGBAmasks[3] = 0x000000FF; + bpp = 32; + cpp = 4; + break; + +#if 0 + case DRM_FORMAT_XRGB2101010: + RGBAmasks[0] = 0x3FF00000; + RGBAmasks[1] = 0x000FFC00; + RGBAmasks[2] = 0x000003FF; + RGBAmasks[3] = 0x00000000; + break; + + case DRM_FORMAT_XBGR2101010: + RGBAmasks[0] = 0x000003FF; + RGBAmasks[1] = 0x000FFC00; + RGBAmasks[2] = 0x3FF00000; + RGBAmasks[3] = 0x00000000; + break; + + case DRM_FORMAT_RGBX1010102: + RGBAmasks[0] = 0xFFC00000; + RGBAmasks[1] = 0x003FF000; + RGBAmasks[2] = 0x00000FFC; + RGBAmasks[3] = 0x00000000; + break; + + case DRM_FORMAT_BGRX1010102: + RGBAmasks[0] = 0x00000FFC; + RGBAmasks[1] = 0x003FF000; + RGBAmasks[2] = 0xFFC00000; + RGBAmasks[3] = 0x00000000; + break; + + case DRM_FORMAT_ARGB2101010: + RGBAmasks[0] = 0x3FF00000; + RGBAmasks[1] = 0x000FFC00; + RGBAmasks[2] = 0x000003FF; + RGBAmasks[3] = 0xC0000000; + break; + + case DRM_FORMAT_ABGR2101010: + RGBAmasks[0] = 0x000003FF; + RGBAmasks[1] = 0x000FFC00; + RGBAmasks[2] = 0x3FF00000; + RGBAmasks[3] = 0xC0000000; + break; + + case DRM_FORMAT_RGBA1010102: + RGBAmasks[0] = 0xFFC00000; + RGBAmasks[1] = 0x003FF000; + RGBAmasks[2] = 0x00000FFC; + RGBAmasks[3] = 0x00000003; + break; + + case DRM_FORMAT_BGRA1010102: + RGBAmasks[0] = 0x00000FFC; + RGBAmasks[1] = 0x003FF000; + RGBAmasks[2] = 0xFFC00000; + RGBAmasks[3] = 0x00000003; + break; +#endif + + default: + break; + } + + if (ret_cpp) + *ret_cpp = cpp; + + return bpp; +} + +static GAL_Surface* create_surface_from_buffer (_THIS, + DrmSurfaceBuffer* surface_buffer, int depth, Uint32 *RGBAmasks) +{ + DrmVideoData* vdata = this->hidden; + GAL_Surface* surface = NULL; + size_t pixels_size = surface_buffer->height * surface_buffer->pitch; + + if (surface_buffer->size < surface_buffer->offset + pixels_size) { + _WRN_PRINTF ("NEWGAL>DRM: the buffer size is not large enought!\n"); + } + + /* for dumb buffer, already mapped */ + if (surface_buffer->buff == NULL && + vdata->driver && vdata->driver_ops->map_buffer) { + if (!vdata->driver_ops->map_buffer(vdata->driver, surface_buffer, 0)) { + _ERR_PRINTF ("NEWGAL>DRM: cannot map hardware buffer: %m\n"); + goto error; + } + } + + /* Allocate the surface */ + surface = (GAL_Surface *)malloc (sizeof(*surface)); + if (surface == NULL) { + goto error; + } + + /* Allocate the format */ + surface->format = GAL_AllocFormat (depth, RGBAmasks[0], RGBAmasks[1], + RGBAmasks[2], RGBAmasks[3]); + if (surface->format == NULL) { + goto error; + } + + /* Allocate an empty mapping */ + surface->map = GAL_AllocBlitMap (); + if (surface->map == NULL) { + goto error; + } + + surface->format_version = 0; + surface->video = this; + surface->flags = GAL_HWSURFACE; + surface->dpi = GDCAP_DPI_DEFAULT; + surface->w = surface_buffer->width; + surface->h = surface_buffer->height; + surface->pitch = surface_buffer->pitch; + surface->offset = 0; + surface->pixels = surface_buffer->buff + surface_buffer->offset; + surface->hwdata = (struct private_hwdata *)surface_buffer; + + /* The surface is ready to go */ + surface->refcount = 1; + + GAL_SetClipRect(surface, NULL); + +#ifdef _MGUSE_UPDATE_REGION + /* Initialize update region */ + InitClipRgn (&surface->update_region, &__mg_free_update_region_list); +#endif + + return(surface); + +error: + if (surface) + GAL_FreeSurface(surface); + + return NULL; +} + +static DrmSurfaceBuffer *drm_create_dumb_buffer(DrmVideoData* vdata, + uint32_t drm_format, uint32_t hdr_size, + int width, int height); + +static void drm_destroy_dumb_buffer(DrmVideoData* vdata, + DrmSurfaceBuffer *surface_buffer); /* * The following helpers derived from DRM HOWTO by David Herrmann. * * drm_prepare * drm_find_crtc * drm_setup_connector - * drm_create_dumb_fb * drm_cleanup * * Copyright 2012-2017 David Herrmann @@ -123,10 +810,12 @@ static int DRM_Available(void) struct drm_mode_info { struct drm_mode_info *next; - uint32_t width; - uint32_t height; - uint32_t conn; - uint32_t crtc; + int width; + int height; + int pitch; + + uint32_t conn; + uint32_t crtc; drmModeModeInfo mode; }; @@ -148,32 +837,17 @@ static void drm_cleanup(DrmVideoData* vdata) &vdata->saved_info->conn, 1, &vdata->saved_crtc->mode); if (ret) { - _ERR_PRINTF ("NEWGAL>DRM: failed to restore CRTC for connector %u (%d): %m\n", - vdata->saved_info->conn, errno); + _ERR_PRINTF ("NEWGAL>DRM: failed to restore CRTC for " + "connector %u (%d): %m\n", + vdata->saved_info->conn, errno); } drmModeFreeCrtc(vdata->saved_crtc); } - if (vdata->scanout_fb) { - if (vdata->driver_ops) { - // do nothing for hardware surface. - } - else { - /* dumb buffer */ - struct drm_mode_destroy_dumb dreq; - - /* unmap buffer */ - munmap(vdata->scanout_fb, vdata->size); - - /* delete framebuffer */ - drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id); - - /* delete dumb buffer */ - memset(&dreq, 0, sizeof(dreq)); - dreq.handle = vdata->handle; - drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); - } + if (vdata->scanout_buff_id) { + /* remove frame buffer */ + drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id); } if (vdata->modes) { @@ -204,6 +878,12 @@ static void DRM_DeleteDevice(GAL_VideoDevice *device) { drm_cleanup(device->hidden); + if (device->hidden->dev_name) + free (device->hidden->dev_name); + + if (device->hidden->ex_driver) + free (device->hidden->ex_driver); + if (device->hidden->driver && device->hidden->driver_ops) { device->hidden->driver_ops->destroy_driver(device->hidden->driver); } @@ -260,28 +940,44 @@ static char* find_driver_for_device (const char *dev_name) return strdup (driver + strlen ("/")); } -#define LEN_DRIVER_FILENAME 255 - static DrmDriverOps* load_external_driver (DrmVideoData* vdata, const char* driver_name, int device_fd) { const char* filename = NULL; - char buff[LEN_DRIVER_FILENAME + 1]; - DrmDriverOps* (*get_exdrv) (const char* driver_name, int device_fd); + char buff[LEN_SO_NAME + 1]; + DrmDriverOps* (*get_exdrv) (const char*, int, int*); char* error; + int version = 0; + DrmDriverOps* ops; - filename = getenv ("MG_GAL_DRM_DRIVER"); - if (filename == NULL) { - memset (buff, 0, sizeof (buff)); - if (GetMgEtcValue ("drm", "exdriver", buff, LEN_DRIVER_FILENAME) < 0) - return NULL; +#ifdef _MGRM_PROCESSES + if (mgIsServer) { +#endif + filename = getenv ("MG_GAL_DRM_DRIVER"); + if (filename == NULL) { + memset (buff, 0, sizeof (buff)); + if (GetMgEtcValue ("drm", "exdriver", buff, LEN_SO_NAME) < 0) { + vdata->ex_driver = strdup("none"); + return NULL; + } - filename = buff; + filename = buff; + } + vdata->ex_driver = strdup(filename); +#ifdef _MGRM_PROCESSES } + else { + filename = SHAREDRES_VIDEO_EXDRIVER; + vdata->ex_driver = strdup(filename); + } +#endif + + if (strcmp(filename, "none") == 0) + return NULL; vdata->exdrv_handle = dlopen (filename, RTLD_LAZY); if (!vdata->exdrv_handle) { - _WRN_PRINTF("Failed to open specified external DRM driver: %s (%s)\n", + _ERR_PRINTF("NEWGAL>DRM: failed to open external DRM driver: %s (%s)\n", filename, dlerror()); return NULL; } @@ -290,58 +986,133 @@ static DrmDriverOps* load_external_driver (DrmVideoData* vdata, get_exdrv = dlsym (vdata->exdrv_handle, "__drm_ex_driver_get"); error = dlerror(); if (error) { - _WRN_PRINTF("Failed to get symbol: %s\n", error); + _ERR_PRINTF("NEWGAL>DRM: failed to get symbol: %s\n", error); dlclose (vdata->exdrv_handle); vdata->exdrv_handle = NULL; return NULL; } - return get_exdrv (driver_name, device_fd); + /* check version here */ + ops = get_exdrv (driver_name, device_fd, &version); + if (version != DRM_DRIVER_VERSION) { + _ERR_PRINTF("NEWGAL>DRM: version does not match: required(%d), got(%d)\n", + DRM_DRIVER_VERSION, version); + dlclose (vdata->exdrv_handle); + vdata->exdrv_handle = NULL; + return NULL; + } + + return ops; } +#ifdef _MGRM_PROCESSES +int __drm_auth_client (int cli, uint32_t magic) +{ + GAL_VideoDevice *this = __mg_current_video; + DrmVideoData* vdata; + + assert (sizeof(uint32_t) == sizeof(drm_magic_t)); + + if (!this || this->VideoInit != DRM_VideoInit) { + return -1; + } + + vdata = this->hidden; + if (drmAuthMagic(vdata->dev_fd, (drm_magic_t)magic)) { + _WRN_PRINTF("NEWGAL>DRM: failed to call drmAuthMagic (%u): %m\n", magic); + return -1; + } + + _DBG_PRINTF("Client (%d) authenticated with magic (%u)\n", cli, magic); + return 0; +} +#endif /* _MGRM_PROCESSES */ + static int open_drm_device(GAL_VideoDevice *device) { char *driver_name; - int device_fd; + int fd; driver_name = find_driver_for_device(device->hidden->dev_name); _DBG_PRINTF("Try to load DRM driver: %s\n", driver_name); - device_fd = drmOpen(driver_name, NULL); - if (device_fd < 0) { + fd = drmOpen(driver_name, NULL); + if (fd < 0) { _ERR_PRINTF("NEWGAL>DRM: drmOpen failed\n"); free(driver_name); return -errno; } - device->hidden->driver_ops = load_external_driver (device->hidden, - driver_name, device_fd); +#ifdef _MGRM_PROCESSES + if (mgIsServer) { + if (drmSetMaster(fd)) { + _ERR_PRINTF("NEWGAL>DRM: failed to call drmSetMaster: %m\n"); + _ERR_PRINTF(" You need to run `mginit` as root.\n"); + return -EACCES; + } + } + else { + drm_magic_t magic; + REQUEST req; + int auth_result; + if (drmGetMagic(fd, &magic)) { + _DBG_PRINTF("failed to call drmGetMagic: %m\n"); + return -errno; + } + + req.id = REQID_AUTHCLIENT; + req.data = &magic; + req.len_data = sizeof (magic); + if ((ClientRequest (&req, &auth_result, sizeof(int)) < 0)) { + _ERR_PRINTF("NEWGAL>DRM: failed to call ClientRequest: %m\n"); + return -ECOMM; + } + + if (auth_result) { + _ERR_PRINTF("NEWGAL>DRM: failed to authenticate: %d\n", auth_result); + return -EACCES; + } + } +#endif /* defined _MGRM_PROCESSES */ + + device->hidden->driver_ops = load_external_driver (device->hidden, + driver_name, fd); free (driver_name); - if (device->hidden->driver_ops == NULL) { + /* get capabilities */ + { uint64_t has_dumb; /* check whether supports dumb buffer */ - if (drmGetCap(device_fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || + if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0 || !has_dumb) { - _ERR_PRINTF("NEWGAL>DRM: the DRM device '%s' does not support dumb buffers\n", - device->hidden->dev_name); - close(device_fd); - return -EOPNOTSUPP; + device->hidden->cap_dumb = 0; + } + else { + device->hidden->cap_dumb = 1; } - - device->hidden->dev_fd = device_fd; - device->hidden->driver = NULL; - return 0; } - device->hidden->dev_fd = device_fd; - device->hidden->driver = device->hidden->driver_ops->create_driver(device_fd); + device->hidden->dev_fd = fd; + if (device->hidden->driver_ops) { + device->hidden->driver = device->hidden->driver_ops->create_driver(fd); + } + if (device->hidden->driver == NULL) { - _WRN_PRINTF("NEWGAL>DRM: failed to create DRM driver\n"); + _WRN_PRINTF("failed to create DRM driver\n"); device->hidden->driver_ops = NULL; + + /* check whether supports dumb buffer */ + if (!device->hidden->cap_dumb) { + _ERR_PRINTF("NEWGAL>DRM: the DRM device '%s' does not support " + "dumb buffers\n", + device->hidden->dev_name); + close(fd); + device->hidden->dev_fd = -1; + return -EOPNOTSUPP; + } } return 0; @@ -349,11 +1120,12 @@ static int open_drm_device(GAL_VideoDevice *device) static GAL_VideoDevice *DRM_CreateDevice(int devindex) { + char dev_name [LEN_DEVICE_NAME + 1]; GAL_VideoDevice *device; /* Initialize all variables that we clean on shutdown */ device = (GAL_VideoDevice *)malloc(sizeof(GAL_VideoDevice)); - if ( device ) { + if (device) { memset(device, 0, (sizeof (*device))); device->hidden = (struct GAL_PrivateVideoData *) calloc(1, (sizeof (*device->hidden))); @@ -367,11 +1139,20 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex) } memset(device->hidden, 0, (sizeof (*device->hidden))); - if (GetMgEtcValue ("drm", "device", - device->hidden->dev_name, LEN_DEVICE_NAME) < 0) { - strcpy(device->hidden->dev_name, "/dev/dri/card0"); - _WRN_PRINTF("NEWGAL>DRM: No dri.device defined, use the default '/dev/dri/card0'\n"); +#ifdef _MGRM_PROCESSES + if (mgIsServer) { +#endif + if (GetMgEtcValue ("drm", "device", dev_name, LEN_DEVICE_NAME) < 0) { + strcpy(dev_name, "/dev/dri/card0"); + _WRN_PRINTF("No drm.device defined, use default '/dev/dri/card0'\n"); + } + device->hidden->dev_name = strdup(dev_name); +#ifdef _MGRM_PROCESSES } + else { + device->hidden->dev_name = strdup (SHAREDRES_VIDEO_DEVICE); + } +#endif device->hidden->dev_fd = -1; open_drm_device(device); @@ -383,27 +1164,43 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex) device->ListModes = DRM_ListModes; device->SetColors = DRM_SetColors; device->VideoQuit = DRM_VideoQuit; + device->AllocHWSurface = DRM_AllocHWSurface_Accl; + device->FreeHWSurface = DRM_FreeHWSurface_Accl; + if (device->hidden->driver) { /* Use accelerated driver */ - device->SetVideoMode = DRM_SetVideoMode_Accl; -#ifndef _MGRM_THREADS - device->RequestHWSurface = NULL; -#endif - device->AllocHWSurface = DRM_AllocHWSurface_Accl; - device->FreeHWSurface = DRM_FreeHWSurface_Accl; - device->UpdateRects = DRM_UpdateRects_Accl; +#ifdef _MGRM_PROCESSES + if (mgIsServer) { + device->SetVideoMode = DRM_SetVideoMode; + } + else { + device->SetVideoMode = DRM_SetVideoMode_Client; + } + device->RequestHWSurface = NULL; // always be NULL + device->CopyVideoInfoToSharedRes = DRM_CopyVideoInfoToSharedRes; +#endif /* defined _MGRM_PROCESSES */ + } else { /* Use DUMB buffer */ - device->SetVideoMode = DRM_SetVideoMode_Dumb; -#ifndef _MGRM_THREADS - device->RequestHWSurface = NULL; -#endif - device->AllocHWSurface = DRM_AllocHWSurface_Dumb; - device->FreeHWSurface = DRM_FreeHWSurface_Dumb; - device->UpdateRects = NULL; +#ifdef _MGRM_PROCESSES + if (mgIsServer) { + device->SetVideoMode = DRM_SetVideoMode; + } + else { + device->SetVideoMode = DRM_SetVideoMode_Client; + } + + device->RequestHWSurface = NULL; // always be NULL + device->CopyVideoInfoToSharedRes = DRM_CopyVideoInfoToSharedRes; +#endif /* defined _MGRM_PROCESSES */ } + if (device->SetVideoMode == NULL) + device->SetVideoMode = DRM_SetVideoMode; + + device->UpdateRects = DRM_UpdateRects; + /* set accelerated methods in DRM_VideoInit */ device->CheckHWBlit = NULL; device->FillHWRect = NULL; @@ -568,8 +1365,8 @@ static int drm_prepare(DrmVideoData* vdata) /* get information for each connector */ conn = drmModeGetConnector(vdata->dev_fd, res->connectors[i]); if (!conn) { - _ERR_PRINTF("NEWGAL>DRM: cannot retrieve DRM connector %u:%u(%d): %m\n", - i, res->connectors[i], errno); + _ERR_PRINTF("NEWGAL>DRM: cannot retrieve DRM connector %u:%u(%d): " + "%m\n", i, res->connectors[i], errno); continue; } @@ -606,40 +1403,54 @@ static int drm_prepare(DrmVideoData* vdata) /* DRM engine methods for both dumb buffer and acclerated buffers */ static int DRM_VideoInit(_THIS, GAL_PixelFormat *vformat) { - int n = 0; - struct drm_mode_info *iter; +#ifdef _MGRM_PROCESSES + if (mgIsServer) +#endif + { + int n = 0; + struct drm_mode_info *iter; - drm_prepare(this->hidden); + drm_prepare(this->hidden); - for (iter = this->hidden->mode_list; iter; iter = iter->next) { - _DBG_PRINTF("mode #%d: %ux%u, conn: %u, crtc: %u\n", n, - iter->width, iter->height, iter->conn, iter->crtc); - n++; + for (iter = this->hidden->mode_list; iter; iter = iter->next) { + _DBG_PRINTF("mode #%d: %ux%u, conn: %u, crtc: %u\n", n, + iter->width, iter->height, iter->conn, iter->crtc); + n++; + } + + if (n == 0) { + return -1; + } + + this->hidden->modes = calloc(n + 1, sizeof(GAL_Rect*)); + if (this->hidden->modes == NULL) { + _ERR_PRINTF("NEWGAL>DRM: failed to allocate memory for modes (%d)\n", + n); + return -1; + } + + n = 0; + for (iter = this->hidden->mode_list; iter; iter = iter->next) { + this->hidden->modes[n] = malloc(sizeof(GAL_Rect)); + this->hidden->modes[n]->x = 0; + this->hidden->modes[n]->y = 0; + this->hidden->modes[n]->w = iter->width; + this->hidden->modes[n]->h = iter->height; + n++; + } + + vformat->BitsPerPixel = 32; + vformat->BytesPerPixel = 4; } +#ifdef _MGRM_PROCESSES + else { + int bpp, cpp; + drm_format_to_bpp (SHAREDRES_VIDEO_DRM_FORMAT, &bpp, &cpp); - if (n == 0) { - return -1; + vformat->BitsPerPixel = bpp; + vformat->BytesPerPixel = cpp; } - - this->hidden->modes = calloc(n + 1, sizeof(GAL_Rect*)); - if (this->hidden->modes == NULL) { - _ERR_PRINTF("NEWGAL>DRM: failed to allocate memory for modes (%d)\n", - n); - return -1; - } - - n = 0; - for (iter = this->hidden->mode_list; iter; iter = iter->next) { - this->hidden->modes[n] = malloc(sizeof(GAL_Rect)); - this->hidden->modes[n]->x = 0; - this->hidden->modes[n]->y = 0; - this->hidden->modes[n]->w = iter->width; - this->hidden->modes[n]->h = iter->height; - n++; - } - - vformat->BitsPerPixel = 32; - vformat->BytesPerPixel = 4; +#endif if (this->hidden->driver) { if (this->hidden->driver_ops->clear_buffer) { @@ -746,82 +1557,330 @@ static int DRM_Suspend(_THIS) return ret; } -/* - * drm_create_dumb_fb(vdata, info): - * Call this function to create a so called "dumb buffer". - * We can use it for unaccelerated software rendering on the CPU. - */ -static int drm_create_dumb_fb(DrmVideoData* vdata, const DrmModeInfo* info, - uint32_t format, int bpp) +#ifdef _MGRM_PROCESSES +static void DRM_CopyVideoInfoToSharedRes(_THIS) +{ + DrmVideoData* vdata = this->hidden; + + SHAREDRES_VIDEO_DRM_FORMAT = + ((DrmSurfaceBuffer*)vdata->real_screen->hwdata)->drm_format; + + strncpy (SHAREDRES_VIDEO_EXDRIVER, vdata->ex_driver, LEN_EXDRIVER_NAME); + SHAREDRES_VIDEO_EXDRIVER[LEN_EXDRIVER_NAME] = 0; + + strncpy (SHAREDRES_VIDEO_DEVICE, vdata->dev_name, LEN_DEVICE_NAME); + SHAREDRES_VIDEO_EXDRIVER[LEN_DEVICE_NAME] = 0; +} +#endif /* _MGRM_PROCESSES */ + +static int drm_setup_scanout_buffer (DrmVideoData* vdata, + uint32_t handle, uint32_t drm_format, + uint32_t width, uint32_t height, uint32_t pitch, uint32_t offset) +{ + uint32_t handles[4], pitches[4], offsets[4]; + int ret; + + handles[0] = handle; + pitches[0] = pitch; + offsets[0] = offset; + + ret = drmModeAddFB2(vdata->dev_fd, width, height, drm_format, + handles, pitches, offsets, &vdata->scanout_buff_id, 0); + if (ret) { + _DBG_PRINTF ("drmModeAddFB2 failed: " + "handle(%u), pitch(%u), offset(%u), w(%u), h(%u), f(%x): %m\n", + handle, pitch, offset, width, height, drm_format); + return ret; + } + + /* perform actual modesetting on the found connector+CRTC */ + vdata->saved_crtc = drmModeGetCrtc(vdata->dev_fd, vdata->saved_info->crtc); + //vdata->console_buff_id = vdata->saved_crtc->buffer_id; + + ret = drmModeSetCrtc(vdata->dev_fd, vdata->saved_info->crtc, + vdata->scanout_buff_id, 0, 0, &vdata->saved_info->conn, 1, + &vdata->saved_info->mode); + if (ret) { + _DBG_PRINTF ("cannot set CRTC for connector %u: %m\n", + vdata->saved_info->conn); + + drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id); + vdata->scanout_buff_id = 0; + + drmModeFreeCrtc(vdata->saved_crtc); + vdata->saved_crtc = NULL; + } + + return ret; +} + +static inline uint32_t nr_lines_for_header (uint32_t header_size, + uint32_t width, uint32_t height, int cpp) +{ + uint32_t min_pitch = width * cpp; + uint32_t nr_lines = header_size / min_pitch; + + if (header_size % min_pitch) + nr_lines++; + + assert (nr_lines > 0); + return nr_lines; +} + +static DrmSurfaceBuffer *drm_create_dumb_buffer(DrmVideoData* vdata, + uint32_t drm_format, uint32_t hdr_size, int width, int height) { struct drm_mode_create_dumb creq; struct drm_mode_destroy_dumb dreq; struct drm_mode_map_dumb mreq; - uint32_t handles[4], pitches[4], offsets[4]; - int ret; + int bpp, cpp, ret; + int nr_header_lines = 0; // the number of lines reserved for header + DrmSurfaceBuffer *surface_buffer = NULL; + + ret = drm_format_to_bpp (drm_format, &bpp, &cpp); + assert (ret == 0); /* create dumb buffer */ memset(&creq, 0, sizeof(creq)); - creq.width = info->width; - creq.height = info->height; + if (hdr_size) { + creq.width = width; + nr_header_lines = nr_lines_for_header (hdr_size, width, height, cpp); + creq.height = height + nr_header_lines; + } + else { + creq.width = width; + creq.height = height; + } creq.bpp = bpp; ret = drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq); if (ret < 0) { - _ERR_PRINTF("NEWGAL>DRM: cannot create dumb buffer (%d): %m\n", - errno); - return -errno; + _ERR_PRINTF("NEWGAL>DRM: Failed to create dumb buffer (%d): %m\n", errno); + return NULL; } - vdata->width = creq.width; - vdata->height = creq.height; - vdata->bpp = creq.bpp; - vdata->pitch = creq.pitch; - vdata->size = creq.size; - vdata->handle = creq.handle; - - /* create framebuffer object for the dumb-buffer */ - handles[0] = vdata->handle; - pitches[0] = vdata->pitch; - offsets[0] = 0; - - ret = drmModeAddFB2(vdata->dev_fd, vdata->width, vdata->height, format, - handles, pitches, offsets, &vdata->scanout_buff_id, 0); - if (ret) { - _ERR_PRINTF("NEWGAL>DRM: cannot create framebuffer (%d): %m\n", - errno); - ret = -errno; + if ((surface_buffer = malloc (sizeof (DrmSurfaceBuffer))) == NULL) { + _ERR_PRINTF("NEWGAL>DRM: Failed to allocate memory\n"); goto err_destroy; } + surface_buffer->handle = creq.handle; + surface_buffer->prime_fd = -1; + surface_buffer->name = 0; + surface_buffer->fb_id = 0; + surface_buffer->drm_format = drm_format; + surface_buffer->width = creq.width; + surface_buffer->height = creq.height - nr_header_lines; + surface_buffer->pitch = creq.pitch; + surface_buffer->bpp = bpp; + surface_buffer->cpp = cpp; + surface_buffer->offset = creq.pitch * nr_header_lines; + surface_buffer->size = creq.size; + + _DBG_PRINTF ("Surface buffer info: handle(%u), w(%u), h(%u), " + "pitch(%u), size(%lu), offset(%lu)\n", + surface_buffer->handle, + surface_buffer->width, surface_buffer->height, + surface_buffer->pitch, + surface_buffer->size, surface_buffer->offset); + /* prepare buffer for memory mapping */ memset(&mreq, 0, sizeof(mreq)); - mreq.handle = vdata->handle; + mreq.handle = surface_buffer->handle; ret = drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq); if (ret) { _ERR_PRINTF("NEWGAL>DRM: cannot map dumb buffer (%d): %m\n", errno); - ret = -errno; goto err_fb; } /* perform actual memory mapping */ - vdata->scanout_fb = mmap(0, vdata->size, PROT_READ | PROT_WRITE, MAP_SHARED, - vdata->dev_fd, mreq.offset); - if (vdata->scanout_fb == MAP_FAILED) { + surface_buffer->buff = mmap(0, surface_buffer->size, + PROT_READ | PROT_WRITE, MAP_SHARED, + vdata->dev_fd, mreq.offset); + if (surface_buffer->buff == MAP_FAILED) { _ERR_PRINTF("NEWGAL>DRM: cannot mmap dumb buffer (%d): %m\n", errno); - ret = -errno; goto err_fb; } - return 0; + return surface_buffer; err_fb: - drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id); + free (surface_buffer); err_destroy: memset(&dreq, 0, sizeof(dreq)); - dreq.handle = vdata->handle; + dreq.handle = creq.handle; drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); - return ret; + return NULL; +} + +static DrmSurfaceBuffer *drm_create_dumb_buffer_from_handle(DrmVideoData* vdata, + uint32_t handle, size_t size) +{ + int ret; + DrmSurfaceBuffer *surface_buffer = NULL; + struct drm_mode_map_dumb mreq; + + if ((surface_buffer = malloc (sizeof (DrmSurfaceBuffer))) == NULL) { + _ERR_PRINTF("NEWGAL>DRM: Failed to allocate memory\n"); + goto error; + } + + surface_buffer->handle = handle; + surface_buffer->prime_fd = -1; + surface_buffer->name = 0; + surface_buffer->fb_id = 0; + surface_buffer->size = size; + + /* prepare buffer for memory mapping */ + memset(&mreq, 0, sizeof(mreq)); + mreq.handle = surface_buffer->handle; + ret = drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_MAP_DUMB, &mreq); + if (ret) { + _ERR_PRINTF("NEWGAL>DRM: cannot map dumb buffer (%u): %m\n", mreq.handle); + goto error; + } + + /* perform actual memory mapping */ + surface_buffer->buff = mmap(0, surface_buffer->size, + PROT_READ | PROT_WRITE, MAP_SHARED, + vdata->dev_fd, mreq.offset); + if (surface_buffer->buff == MAP_FAILED) { + _ERR_PRINTF("NEWGAL>DRM: cannot mmap dumb buffer (%u): %m\n", errno); + goto error; + } + + return surface_buffer; + +error: + if (surface_buffer) + free (surface_buffer); + + return NULL; +} + +static DrmSurfaceBuffer *drm_create_dumb_buffer_from_name(DrmVideoData* vdata, + uint32_t name) +{ + int ret; + struct drm_gem_open oreq; + DrmSurfaceBuffer *surface_buffer = NULL; + + /* open named buffer */ + memset(&oreq, 0, sizeof(oreq)); + oreq.name = name; + ret = drmIoctl(vdata->dev_fd, DRM_IOCTL_GEM_OPEN, &oreq); + if (ret < 0) { + _ERR_PRINTF("NEWGAL>DRM: Failed to open named buffer (%u): %m\n", name); + return NULL; + } + + surface_buffer = drm_create_dumb_buffer_from_handle (vdata, + oreq.handle, oreq.size); + + if (surface_buffer == NULL) { + struct drm_gem_close creq; + memset(&creq, 0, sizeof(creq)); + creq.handle = oreq.handle; + drmIoctl(vdata->dev_fd, DRM_IOCTL_GEM_CLOSE, &creq); + } + + surface_buffer->handle = oreq.handle; + surface_buffer->prime_fd = -1; + surface_buffer->name = name; + surface_buffer->fb_id = 0; + surface_buffer->size = oreq.size; + + return surface_buffer; +} + +static DrmSurfaceBuffer *drm_create_dumb_buffer_from_prime_fd(DrmVideoData* vdata, + int prime_fd, size_t size) +{ + int ret; + uint32_t handle; + DrmSurfaceBuffer *surface_buffer; + + if (size == 0) { + off_t seek = lseek (prime_fd, 0, SEEK_END); + if (seek != -1) + size = seek; + else { + _ERR_PRINTF("NEWGAL>DRM: Failed to get size of buffer from fd (%d): " + "%m\n", prime_fd); + return NULL; + } + + _DBG_PRINTF("size got by calling lseek: %lu\n", size); + } + + ret = drmPrimeFDToHandle (vdata->dev_fd, prime_fd, &handle); + if (ret) { + _ERR_PRINTF ("NEWGAL>DRM: failed to obtain handle from fd (%d): %m\n", + prime_fd); + return NULL; + } + +#if 0 + surface_buffer->handle = 0; + surface_buffer->size = size; + + /* perform actual memory mapping */ + surface_buffer->buff = mmap(0, size, + PROT_READ | PROT_WRITE, MAP_SHARED, prime_fd, 0); + if (surface_buffer->buff == MAP_FAILED) { + _ERR_PRINTF("NEWGAL>DRM: cannot mmap dumb buffer for prime fd (%d): " + "%m\n", prime_fd); + goto error; + } +#else + surface_buffer = drm_create_dumb_buffer_from_handle (vdata, handle, size); + if (surface_buffer == NULL) { + struct drm_mode_destroy_dumb dreq; + memset(&dreq, 0, sizeof(dreq)); + dreq.handle = handle; + drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); + } +#endif + + surface_buffer->handle = handle; + surface_buffer->prime_fd = prime_fd; + surface_buffer->name = 0; + surface_buffer->fb_id = 0; + surface_buffer->size = size; + + return surface_buffer; +} + +static void drm_destroy_dumb_buffer(DrmVideoData* vdata, + DrmSurfaceBuffer *surface_buffer) +{ + if (surface_buffer->fb_id) { + drmModeRmFB (vdata->dev_fd, surface_buffer->fb_id); + } + + if (surface_buffer->buff) + munmap (surface_buffer->buff, surface_buffer->size); + + assert (surface_buffer->handle); + + if (surface_buffer->prime_fd >= 0) + close (surface_buffer->prime_fd); + + if (surface_buffer->name) { + struct drm_gem_close creq; + memset(&creq, 0, sizeof(creq)); + creq.handle = surface_buffer->handle; + drmIoctl(vdata->dev_fd, DRM_IOCTL_GEM_CLOSE, &creq); + } + else { + struct drm_mode_destroy_dumb dreq; + + memset (&dreq, 0, sizeof(dreq)); + dreq.handle = surface_buffer->handle; + drmIoctl(vdata->dev_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); + } + + free (surface_buffer); } static DrmModeInfo* find_mode(DrmVideoData* vdata, int width, int height) @@ -836,503 +1895,14 @@ static DrmModeInfo* find_mode(DrmVideoData* vdata, int width, int height) return NULL; } -static inline uint32_t get_def_drm_format(int bpp) -{ - switch (bpp) { - case 32: - return DRM_FORMAT_XRGB8888; - case 24: - return DRM_FORMAT_RGB888; - case 16: - return DRM_FORMAT_RGB565; - case 8: - return DRM_FORMAT_RGB332; - default: - break; - } - - return DRM_FORMAT_RGB565; -} - -static uint32_t get_drm_format_from_etc(int* bpp) -{ - uint32_t format; - char fourcc[8] = {}; - - if (GetMgEtcValue ("drm", "pixelformat", - fourcc, 4) < 0) { - return get_def_drm_format(*bpp); - } - - format = fourcc_code(fourcc[0], fourcc[1], fourcc[2], fourcc[3]); - switch (format) { - case DRM_FORMAT_RGB332: - case DRM_FORMAT_BGR233: - *bpp = 8; - break; - - case DRM_FORMAT_XRGB4444: - case DRM_FORMAT_XBGR4444: - case DRM_FORMAT_RGBX4444: - case DRM_FORMAT_BGRX4444: - case DRM_FORMAT_ARGB4444: - case DRM_FORMAT_ABGR4444: - case DRM_FORMAT_RGBA4444: - case DRM_FORMAT_BGRA4444: - case DRM_FORMAT_XRGB1555: - case DRM_FORMAT_XBGR1555: - case DRM_FORMAT_RGBX5551: - case DRM_FORMAT_BGRX5551: - case DRM_FORMAT_ARGB1555: - case DRM_FORMAT_ABGR1555: - case DRM_FORMAT_RGBA5551: - case DRM_FORMAT_BGRA5551: - case DRM_FORMAT_RGB565: - case DRM_FORMAT_BGR565: - *bpp = 16; - break; - - case DRM_FORMAT_RGB888: - case DRM_FORMAT_BGR888: - *bpp = 24; - break; - - case DRM_FORMAT_XRGB8888: - case DRM_FORMAT_XBGR8888: - case DRM_FORMAT_RGBX8888: - case DRM_FORMAT_BGRX8888: - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_RGBA8888: - case DRM_FORMAT_BGRA8888: -#if 0 - case DRM_FORMAT_XRGB2101010: - case DRM_FORMAT_XBGR2101010: - case DRM_FORMAT_RGBX1010102: - case DRM_FORMAT_BGRX1010102: - case DRM_FORMAT_ARGB2101010: - case DRM_FORMAT_ABGR2101010: - case DRM_FORMAT_RGBA1010102: - case DRM_FORMAT_BGRA1010102: -#endif - *bpp = 32; - break; - default: - _ERR_PRINTF("NEWGAL>DRM: not supported pixel format: %s\n", - fourcc); - return 0; - break; - } - - return format; -} - -struct rgbamasks_drm_format_map { - uint32_t drm_format; - Uint32 Rmask, Gmask, Bmask, Amask; -}; - -static struct rgbamasks_drm_format_map _format_map_8bpp [] = { - { DRM_FORMAT_RGB332, 0xE0, 0x1C, 0x03, 0x00 }, - { DRM_FORMAT_BGR233, 0x0E, 0x38, 0xC0, 0x00 }, -}; - -static struct rgbamasks_drm_format_map _format_map_16bpp [] = { - { DRM_FORMAT_XRGB4444, 0x0F00, 0x00F0, 0x000F, 0x0000 }, - { DRM_FORMAT_XBGR4444, 0x000F, 0x00F0, 0x0F00, 0x0000 }, - { DRM_FORMAT_RGBX4444, 0xF000, 0x0F00, 0x00F0, 0x0000 }, - { DRM_FORMAT_BGRX4444, 0x00F0, 0x0F00, 0xF000, 0x0000 }, - { DRM_FORMAT_ARGB4444, 0x0F00, 0x00F0, 0x000F, 0xF000 }, - { DRM_FORMAT_ABGR4444, 0x000F, 0x00F0, 0x0F00, 0xF000 }, - { DRM_FORMAT_RGBA4444, 0xF000, 0x0F00, 0x00F0, 0x000F }, - { DRM_FORMAT_BGRA4444, 0x00F0, 0x0F00, 0xF000, 0x000F }, - { DRM_FORMAT_XRGB1555, 0x7C00, 0x03E0, 0x001F, 0x0000 }, - { DRM_FORMAT_XBGR1555, 0x001F, 0x03E0, 0x7C00, 0x0000 }, - { DRM_FORMAT_RGBX5551, 0xF800, 0x07C0, 0x003E, 0x0000 }, - { DRM_FORMAT_BGRX5551, 0x003E, 0x07C0, 0xF800, 0x0000 }, - { DRM_FORMAT_ARGB1555, 0x7C00, 0x03E0, 0x001F, 0x8000 }, - { DRM_FORMAT_ABGR1555, 0x001F, 0x03E0, 0x7C00, 0x8000 }, - { DRM_FORMAT_RGBA5551, 0xF800, 0x07C0, 0x003E, 0x0001 }, - { DRM_FORMAT_BGRA5551, 0x003E, 0x07C0, 0xF800, 0x0001 }, - { DRM_FORMAT_RGB565, 0xF800, 0x07E0, 0x001F, 0x0000 }, - { DRM_FORMAT_BGR565, 0x001F, 0x07E0, 0xF800, 0x0000 }, -}; - -static struct rgbamasks_drm_format_map _format_map_24bpp [] = { - { DRM_FORMAT_RGB888, 0xFF0000, 0x00FF00, 0x0000FF, 0x000000 }, - { DRM_FORMAT_BGR888, 0x0000FF, 0x00FF00, 0xFF0000, 0x000000 }, -}; - -static struct rgbamasks_drm_format_map _format_map_32bpp [] = { - { DRM_FORMAT_XRGB8888, 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, - { DRM_FORMAT_XBGR8888, 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 }, - { DRM_FORMAT_RGBX8888, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, - { DRM_FORMAT_BGRX8888, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, - { DRM_FORMAT_ARGB8888, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, - { DRM_FORMAT_ABGR8888, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, - { DRM_FORMAT_RGBA8888, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, - { DRM_FORMAT_BGRA8888, 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, -}; - -static uint32_t translate_gal_format(const GAL_PixelFormat *gal_format) -{ - struct rgbamasks_drm_format_map* map; - size_t i, n; - - switch (gal_format->BitsPerPixel) { - case 8: - map = _format_map_8bpp; - n = TABLESIZE(_format_map_8bpp); - break; - - case 16: - map = _format_map_16bpp; - n = TABLESIZE(_format_map_16bpp); - break; - - case 24: - map = _format_map_24bpp; - n = TABLESIZE(_format_map_24bpp); - break; - - case 32: - map = _format_map_32bpp; - n = TABLESIZE(_format_map_32bpp); - break; - - default: - return 0; - } - - for (i = 0; i < n; i++) { - if (gal_format->Rmask == map[i].Rmask && - gal_format->Gmask == map[i].Gmask && - gal_format->Bmask == map[i].Bmask && - gal_format->Amask == map[i].Amask) { - return map[i].drm_format; - } - } - - return 0; -} - -static int translate_drm_format(uint32_t drm_format, Uint32* RGBAmasks) -{ - int bpp = 0; - - switch (drm_format) { - case DRM_FORMAT_RGB332: - RGBAmasks[0] = 0xE0; - RGBAmasks[1] = 0x1C; - RGBAmasks[2] = 0x03; - RGBAmasks[3] = 0x00; - bpp = 8; - break; - - case DRM_FORMAT_BGR233: - RGBAmasks[0] = 0x0E; - RGBAmasks[1] = 0x38; - RGBAmasks[2] = 0xC0; - RGBAmasks[3] = 0x00; - bpp = 8; - break; - - case DRM_FORMAT_XRGB4444: - RGBAmasks[0] = 0x0F00; - RGBAmasks[1] = 0x00F0; - RGBAmasks[2] = 0x000F; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_XBGR4444: - RGBAmasks[0] = 0x000F; - RGBAmasks[1] = 0x00F0; - RGBAmasks[2] = 0x0F00; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_RGBX4444: - RGBAmasks[0] = 0xF000; - RGBAmasks[1] = 0x0F00; - RGBAmasks[2] = 0x00F0; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_BGRX4444: - RGBAmasks[0] = 0x00F0; - RGBAmasks[1] = 0x0F00; - RGBAmasks[2] = 0xF000; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_ARGB4444: - RGBAmasks[0] = 0x0F00; - RGBAmasks[1] = 0x00F0; - RGBAmasks[2] = 0x000F; - RGBAmasks[3] = 0xF000; - bpp = 16; - break; - - case DRM_FORMAT_ABGR4444: - RGBAmasks[0] = 0x000F; - RGBAmasks[1] = 0x00F0; - RGBAmasks[2] = 0x0F00; - RGBAmasks[3] = 0xF000; - bpp = 16; - break; - - case DRM_FORMAT_RGBA4444: - RGBAmasks[0] = 0xF000; - RGBAmasks[1] = 0x0F00; - RGBAmasks[2] = 0x00F0; - RGBAmasks[3] = 0x000F; - bpp = 16; - break; - - case DRM_FORMAT_BGRA4444: - RGBAmasks[0] = 0x00F0; - RGBAmasks[1] = 0x0F00; - RGBAmasks[2] = 0xF000; - RGBAmasks[3] = 0x000F; - bpp = 16; - break; - - case DRM_FORMAT_XRGB1555: - RGBAmasks[0] = 0x7C00; - RGBAmasks[1] = 0x03E0; - RGBAmasks[2] = 0x001F; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_XBGR1555: - RGBAmasks[0] = 0x001F; - RGBAmasks[1] = 0x03E0; - RGBAmasks[2] = 0x7C00; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_RGBX5551: - RGBAmasks[0] = 0xF800; - RGBAmasks[1] = 0x07C0; - RGBAmasks[2] = 0x003E; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_BGRX5551: - RGBAmasks[0] = 0x003E; - RGBAmasks[1] = 0x07C0; - RGBAmasks[2] = 0xF800; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_ARGB1555: - RGBAmasks[0] = 0x7C00; - RGBAmasks[1] = 0x03E0; - RGBAmasks[2] = 0x001F; - RGBAmasks[3] = 0x8000; - bpp = 16; - break; - - case DRM_FORMAT_ABGR1555: - RGBAmasks[0] = 0x001F; - RGBAmasks[1] = 0x03E0; - RGBAmasks[2] = 0x7C00; - RGBAmasks[3] = 0x8000; - bpp = 16; - break; - - case DRM_FORMAT_RGBA5551: - RGBAmasks[0] = 0xF800; - RGBAmasks[1] = 0x07C0; - RGBAmasks[2] = 0x003E; - RGBAmasks[3] = 0x0001; - bpp = 16; - break; - - case DRM_FORMAT_BGRA5551: - RGBAmasks[0] = 0x003E; - RGBAmasks[1] = 0x07C0; - RGBAmasks[2] = 0xF800; - RGBAmasks[3] = 0x0001; - bpp = 16; - break; - - case DRM_FORMAT_RGB565: - RGBAmasks[0] = 0xF800; - RGBAmasks[1] = 0x07E0; - RGBAmasks[2] = 0x001F; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_BGR565: - RGBAmasks[0] = 0x001F; - RGBAmasks[1] = 0x07E0; - RGBAmasks[2] = 0xF800; - RGBAmasks[3] = 0x0000; - bpp = 16; - break; - - case DRM_FORMAT_RGB888: - RGBAmasks[0] = 0xFF0000; - RGBAmasks[1] = 0x00FF00; - RGBAmasks[2] = 0x0000FF; - RGBAmasks[3] = 0x000000; - bpp = 24; - break; - - case DRM_FORMAT_BGR888: - RGBAmasks[0] = 0x0000FF; - RGBAmasks[1] = 0x00FF00; - RGBAmasks[2] = 0xFF0000; - RGBAmasks[3] = 0x000000; - bpp = 24; - break; - - case DRM_FORMAT_XRGB8888: - RGBAmasks[0] = 0x00FF0000; - RGBAmasks[1] = 0x0000FF00; - RGBAmasks[2] = 0x000000FF; - RGBAmasks[3] = 0x00000000; - bpp = 32; - break; - - case DRM_FORMAT_XBGR8888: - RGBAmasks[0] = 0x000000FF; - RGBAmasks[1] = 0x0000FF00; - RGBAmasks[2] = 0x00FF0000; - RGBAmasks[3] = 0x00000000; - bpp = 32; - break; - - case DRM_FORMAT_RGBX8888: - RGBAmasks[0] = 0xFF000000; - RGBAmasks[1] = 0x00FF0000; - RGBAmasks[2] = 0x0000FF00; - RGBAmasks[3] = 0x00000000; - bpp = 32; - break; - - case DRM_FORMAT_BGRX8888: - RGBAmasks[0] = 0x0000FF00; - RGBAmasks[1] = 0x00FF0000; - RGBAmasks[2] = 0xFF000000; - RGBAmasks[3] = 0x00000000; - bpp = 32; - break; - - case DRM_FORMAT_ARGB8888: - RGBAmasks[0] = 0x00FF0000; - RGBAmasks[1] = 0x0000FF00; - RGBAmasks[2] = 0x000000FF; - RGBAmasks[3] = 0xFF000000; - bpp = 32; - break; - - case DRM_FORMAT_ABGR8888: - RGBAmasks[0] = 0x000000FF; - RGBAmasks[1] = 0x0000FF00; - RGBAmasks[2] = 0x00FF0000; - RGBAmasks[3] = 0xFF000000; - bpp = 32; - break; - - case DRM_FORMAT_RGBA8888: - RGBAmasks[0] = 0xFF000000; - RGBAmasks[1] = 0x00FF0000; - RGBAmasks[2] = 0x0000FF00; - RGBAmasks[3] = 0x000000FF; - bpp = 32; - break; - - case DRM_FORMAT_BGRA8888: - RGBAmasks[0] = 0x0000FF00; - RGBAmasks[1] = 0x00FF0000; - RGBAmasks[2] = 0xFF000000; - RGBAmasks[3] = 0x000000FF; - bpp = 32; - break; - -#if 0 - case DRM_FORMAT_XRGB2101010: - RGBAmasks[0] = 0x3FF00000; - RGBAmasks[1] = 0x000FFC00; - RGBAmasks[2] = 0x000003FF; - RGBAmasks[3] = 0x00000000; - break; - - case DRM_FORMAT_XBGR2101010: - RGBAmasks[0] = 0x000003FF; - RGBAmasks[1] = 0x000FFC00; - RGBAmasks[2] = 0x3FF00000; - RGBAmasks[3] = 0x00000000; - break; - - case DRM_FORMAT_RGBX1010102: - RGBAmasks[0] = 0xFFC00000; - RGBAmasks[1] = 0x003FF000; - RGBAmasks[2] = 0x00000FFC; - RGBAmasks[3] = 0x00000000; - break; - - case DRM_FORMAT_BGRX1010102: - RGBAmasks[0] = 0x00000FFC; - RGBAmasks[1] = 0x003FF000; - RGBAmasks[2] = 0xFFC00000; - RGBAmasks[3] = 0x00000000; - break; - - case DRM_FORMAT_ARGB2101010: - RGBAmasks[0] = 0x3FF00000; - RGBAmasks[1] = 0x000FFC00; - RGBAmasks[2] = 0x000003FF; - RGBAmasks[3] = 0xC0000000; - break; - - case DRM_FORMAT_ABGR2101010: - RGBAmasks[0] = 0x000003FF; - RGBAmasks[1] = 0x000FFC00; - RGBAmasks[2] = 0x3FF00000; - RGBAmasks[3] = 0xC0000000; - break; - - case DRM_FORMAT_RGBA1010102: - RGBAmasks[0] = 0xFFC00000; - RGBAmasks[1] = 0x003FF000; - RGBAmasks[2] = 0x00000FFC; - RGBAmasks[3] = 0x00000003; - break; - - case DRM_FORMAT_BGRA1010102: - RGBAmasks[0] = 0x00000FFC; - RGBAmasks[1] = 0x003FF000; - RGBAmasks[2] = 0xFFC00000; - RGBAmasks[3] = 0x00000003; - break; -#endif - - default: - break; - } - - return bpp; -} - /* DRM engine methods for dumb buffers */ -static GAL_Surface *DRM_SetVideoMode_Dumb(_THIS, GAL_Surface *current, +static GAL_Surface *DRM_SetVideoMode(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags) { uint32_t drm_format; DrmVideoData* vdata = this->hidden; DrmModeInfo* info; + DrmSurfaceBuffer *real_buffer = NULL; Uint32 RGBAmasks[4]; int ret; @@ -1341,10 +1911,16 @@ static GAL_Surface *DRM_SetVideoMode_Dumb(_THIS, GAL_Surface *current, return NULL; } + if (translate_drm_format(drm_format, RGBAmasks, NULL) == 0) { + _ERR_PRINTF("NEWGAL>DRM: not supported DRM format: %u\n", + drm_format); + return NULL; + } + /* find the connector+CRTC suitable for the resolution requested */ info = find_mode(vdata, width, height); if (info == NULL) { - _ERR_PRINTF("NEWGAL>DRM: cannot find a CRTC for video mode: %dx%d-%dbpp\n", + _ERR_PRINTF("NEWGAL>DRM: cannot find a CRTC for video mode: %dx%d-%d\n", width, height, bpp); return NULL; } @@ -1352,235 +1928,195 @@ static GAL_Surface *DRM_SetVideoMode_Dumb(_THIS, GAL_Surface *current, _DBG_PRINTF("going setting video mode: %dx%d-%dbpp\n", info->width, info->height, bpp); - /* create a dumb framebuffer for current CRTC */ - ret = drm_create_dumb_fb(this->hidden, info, drm_format, bpp); + if (vdata->driver) { + assert (vdata->driver_ops->create_buffer); + real_buffer = vdata->driver_ops->create_buffer(vdata->driver, + drm_format, 0, info->width, info->height); + vdata->driver_ops->map_buffer(vdata->driver, real_buffer, 1); + } + else { + real_buffer = drm_create_dumb_buffer (vdata, drm_format, 0, + info->width, info->height); + } + + if (real_buffer == NULL || real_buffer->buff == NULL) { + _ERR_PRINTF("NEWGAL>DRM: " + "failed to create and map buffer for real screen\n"); + return NULL; + } + + vdata->saved_info = info; + + /* setup real_buffer as the scanout buffer */ + ret = drm_setup_scanout_buffer (vdata, real_buffer->handle, + real_buffer->drm_format, real_buffer->width, real_buffer->height, + real_buffer->pitch, real_buffer->offset); if (ret) { - _ERR_PRINTF("NEWGAL>DRM: cannot create dumb framebuffer\n"); - return NULL; - } - - /* perform actual modesetting on the found connector+CRTC */ - this->hidden->saved_crtc = drmModeGetCrtc(vdata->dev_fd, info->crtc); - ret = drmModeSetCrtc(vdata->dev_fd, info->crtc, vdata->scanout_buff_id, 0, 0, - &info->conn, 1, &info->mode); - if (ret) { - _ERR_PRINTF ("NEWGAL>DRM: cannot set CRTC for connector %u (%d): %m\n", - info->conn, errno); - - drmModeFreeCrtc(this->hidden->saved_crtc); - this->hidden->saved_crtc = NULL; - return NULL; - } - - this->hidden->saved_info = info; - - /* Set up the new mode framebuffer */ - /* Allocate the new pixel format for the screen */ - if (translate_drm_format(drm_format, RGBAmasks) == 0) { - _ERR_PRINTF("NEWGAL>DRM: not supported drm format: %u\n", - drm_format); - return NULL; - } - - if (!GAL_ReallocFormat (current, bpp, RGBAmasks[0], RGBAmasks[1], - RGBAmasks[2], RGBAmasks[3])) { - _ERR_PRINTF ("NEWGAL>DRM: " - "failed to allocate new pixel format for requested mode\n"); - return NULL; - } - - _DBG_PRINTF("real screen mode: %dx%d-%dbpp\n", - width, height, bpp); - - current->flags = flags & GAL_FULLSCREEN; - current->w = width; - current->h = height; - current->pitch = this->hidden->pitch; - current->pixels = this->hidden->scanout_fb; - - /* We're done */ - return(current); -} - -static int DRM_AllocHWSurface_Dumb(_THIS, GAL_Surface *surface) -{ - return(-1); -} - -static void DRM_FreeHWSurface_Dumb(_THIS, GAL_Surface *surface) -{ - surface->pixels = NULL; -} - -/* DRM engine methods for accelerated buffers */ -static GAL_Surface *DRM_SetVideoMode_Accl(_THIS, GAL_Surface *current, - int width, int height, int bpp, Uint32 flags) -{ - DrmVideoData* vdata = this->hidden; - DrmModeInfo* info; - uint32_t drm_format; - Uint32 RGBAmasks[4]; - DrmSurfaceBuffer* scanout_buff = NULL; - - drm_format = get_drm_format_from_etc(&bpp); - if (drm_format == 0) { - return NULL; - } - - /* find the connector+CRTC suitable for the resolution requested */ - info = find_mode(vdata, width, height); - if (info == NULL) { - _ERR_PRINTF("NEWGAL>DRM: cannot find a CRTC for video mode: %dx%d-%dbpp\n", - width, height, bpp); - return NULL; - } - - _DBG_PRINTF("going setting video mode: %dx%d-%dbpp\n", - info->width, info->height, bpp); - -#if 0 - if (drmSetMaster(this->hidden->dev_fd)) { - _ERR_PRINTF("NEWGAL>DRM: failed to call drmSetMaster: %m\n"); - return NULL; - } -#endif - - /* create the scanout buffer */ - scanout_buff = vdata->driver_ops->create_buffer(vdata->driver, drm_format, - info->width, info->height); - if (scanout_buff == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: cannot create scanout buffer: %m\n"); + _ERR_PRINTF("NEWGAL>DRM: cannot setup scanout buffer\n"); goto error; } - /* set up it as frame buffer */ - { - uint32_t handles[4], pitches[4], offsets[4]; - handles[0] = scanout_buff->handle; - pitches[0] = scanout_buff->pitch; - offsets[0] = 0; - - if (drmModeAddFB2(vdata->dev_fd, - info->width, info->height, drm_format, - handles, pitches, offsets, &scanout_buff->id, 0) != 0) { - _ERR_PRINTF ("NEWGAL>DRM: cannot set up scanout frame buffer: %m\n"); - goto error; - } - } - - /* not a foreign surface */ - scanout_buff->foreign = 0; - - if (NULL == vdata->driver_ops->map_buffer(vdata->driver, scanout_buff)) { - _ERR_PRINTF ("NEWGAL>DRM: cannot map scanout frame buffer: %m\n"); + vdata->real_screen = create_surface_from_buffer (this, real_buffer, + bpp, RGBAmasks); + if (vdata->real_screen == NULL) goto error; - } - vdata->width = info->width; - vdata->height = info->height; - vdata->bpp = bpp; - vdata->pitch = scanout_buff->pitch; - vdata->size = scanout_buff->pitch * info->height; - vdata->handle = 0; - vdata->scanout_buff_id = scanout_buff->id; - vdata->scanout_fb = scanout_buff->pixels; - - _DBG_PRINTF("scanout frame buffer: size (%dx%d), pitch(%d)\n", - vdata->width, vdata->height, vdata->pitch); - - /* get console buffer id */ - vdata->saved_crtc = drmModeGetCrtc(vdata->dev_fd, info->crtc); - vdata->console_buff_id = vdata->saved_crtc->buffer_id; - - /* perform actual modesetting on the found connector+CRTC */ - if (drmModeSetCrtc(vdata->dev_fd, info->crtc, vdata->scanout_buff_id, 0, 0, - &info->conn, 1, &info->mode)) { - _ERR_PRINTF ("NEWGAL>DRM: cannot set CRTC for connector %u (%d): %m\n", - info->conn, errno); - - goto error; - } - - this->hidden->saved_info = info; - - /* Allocate the new pixel format for the screen */ - if (translate_drm_format(drm_format, RGBAmasks) == 0) { - _ERR_PRINTF("NEWGAL>DRM: not supported drm format: %u\n", - drm_format); - return NULL; - } - - if (!GAL_ReallocFormat (current, bpp, RGBAmasks[0], RGBAmasks[1], - RGBAmasks[2], RGBAmasks[3])) { - _ERR_PRINTF ("NEWGAL>DRM: " - "failed to allocate new pixel format for requested mode\n"); - return NULL; - } - - _DBG_PRINTF("real screen mode: %dx%d-%dbpp\n", - width, height, bpp); - - current->flags |= (GAL_FULLSCREEN | GAL_HWSURFACE); - current->w = width; - current->h = height; - current->pitch = this->hidden->pitch; - current->pixels = this->hidden->scanout_fb; - current->hwdata = (struct private_hwdata *)scanout_buff; - - /* We're done */ - return(current); + GAL_FreeSurface (current); + return vdata->real_screen; error: + if (vdata->scanout_buff_id) { + drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id); + vdata->scanout_buff_id = 0; - if (vdata->saved_crtc) { drmModeFreeCrtc(vdata->saved_crtc); vdata->saved_crtc = NULL; } - if (scanout_buff) { - vdata->driver_ops->unmap_buffer(vdata->driver, scanout_buff); - vdata->scanout_fb = NULL; + if (vdata->real_screen) { + GAL_FreeSurface (vdata->real_screen); + vdata->real_screen = NULL; } - - if (vdata->scanout_buff_id) { - vdata->driver_ops->destroy_buffer(vdata->driver, scanout_buff); - vdata->scanout_buff_id = 0; + else if (real_buffer) { + if (vdata->driver) { + if (real_buffer->buff) + vdata->driver_ops->unmap_buffer(vdata->driver, real_buffer); + vdata->driver_ops->destroy_buffer(vdata->driver, real_buffer); + } + else { + drm_destroy_dumb_buffer (vdata, real_buffer); + } } return NULL; } +#ifdef _MGRM_PROCESSES + +int __drm_get_shared_screen_surface (const char *name, SHAREDSURFINFO* info) +{ + GAL_VideoDevice *this = __mg_current_video; + DrmVideoData* vdata = this->hidden; + DrmSurfaceBuffer* surface_buffer = NULL; + + if (strcmp (name, SYSSF_REAL_SCREEN) == 0) { + assert (vdata->real_screen); + + surface_buffer = (DrmSurfaceBuffer *)vdata->real_screen->hwdata; + + if (vdata->real_name == 0) { + struct drm_gem_flink flink; + + memset (&flink, 0, sizeof (flink)); + flink.handle = surface_buffer->handle; + if (drmIoctl(vdata->dev_fd, DRM_IOCTL_GEM_FLINK, &flink)) { + _ERR_PRINTF ("NEWGAL>DRM: failed to flink real screen\n"); + return -1; + } + + _DBG_PRINTF ("flink name of real screen: %u\n", flink.name); + vdata->real_name = flink.name; + } + + info->flags = vdata->real_screen->flags; + info->width = surface_buffer->width; + info->height = surface_buffer->height; + info->pitch = surface_buffer->pitch; + info->name = vdata->real_name; + + info->drm_format = surface_buffer->drm_format; + info->size = surface_buffer->size; + info->offset = surface_buffer->offset; + } + else { + memset (info, 0, sizeof (*info)); + } + + return 0; +} + +/* DRM engine method for clients under sharedfb schema and MiniGUI-Processes */ +static GAL_Surface *DRM_SetVideoMode_Client(_THIS, GAL_Surface *current, + int width, int height, int bpp, Uint32 flags) +{ + DrmVideoData* vdata = this->hidden; + REQUEST req; + SHAREDSURFINFO info; + + req.id = REQID_GETSHAREDSURFACE; + req.data = SYSSF_REAL_SCREEN; + req.len_data = strlen (SYSSF_REAL_SCREEN) + 1; + + if ((ClientRequestEx (&req, NULL, 0, &info, sizeof (SHAREDSURFINFO)) < 0)) { + goto error; + } + + _DBG_PRINTF ("REQID_GETSHAREDSURFACE for %s: name(%u), flags(%x), " + "size (%lu), offset (%lu)\n", + SYSSF_REAL_SCREEN, + info.name, info.flags, info.size, info.offset); + + vdata->real_screen = __drm_create_surface_from_name (this, info.name, + info.drm_format, info.offset, info.width, info.height, info.pitch); + + if (vdata->real_screen == NULL) { + _ERR_PRINTF ("NEWGAL>DRM: failed to create real screen surface: %u!\n", + info.name); + goto error; + } + + GAL_FreeSurface (current); + return vdata->real_screen; + +error: + if (vdata->real_screen) { + GAL_FreeSurface (vdata->real_screen); + } + + return NULL; +} +#endif /* defined _MGRM_PROCESSES */ + static int DRM_AllocHWSurface_Accl(_THIS, GAL_Surface *surface) { DrmVideoData* vdata = this->hidden; uint32_t drm_format; DrmSurfaceBuffer* surface_buffer; + if (!vdata->driver) + return -1; + drm_format = translate_gal_format(surface->format); if (drm_format == 0) { - _ERR_PRINTF("NEWGAL>DRM: not supported pixel format, RGBA masks (0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", - surface->format->Rmask, surface->format->Gmask, - surface->format->Bmask, surface->format->Amask); + _ERR_PRINTF("NEWGAL>DRM: not supported pixel format, " + "RGBA masks (0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", + surface->format->Rmask, surface->format->Gmask, + surface->format->Bmask, surface->format->Amask); return -1; } surface_buffer = vdata->driver_ops->create_buffer(vdata->driver, drm_format, - surface->w, surface->h); + 0, surface->w, surface->h); if (surface_buffer == NULL) { return -1; } - /* not a foreign surface */ - surface_buffer->foreign = 0; - if (vdata->driver_ops->map_buffer(vdata->driver, surface_buffer) == NULL) { + if (!vdata->driver_ops->map_buffer(vdata->driver, surface_buffer, 0)) { _ERR_PRINTF ("NEWGAL>DRM: cannot map hardware buffer: %m\n"); goto error; } - surface->pixels = surface_buffer->pixels; - surface->flags |= GAL_HWSURFACE; surface->pitch = surface_buffer->pitch; + surface->pixels = surface_buffer->buff + surface_buffer->offset; + surface->flags |= GAL_HWSURFACE; surface->hwdata = (struct private_hwdata *)surface_buffer; + + _DBG_PRINTF("allocated hardware surface: w(%d), h(%d), pitch(%d), " + "RGBA masks (0x%08x, 0x%08x, 0x%08x, 0x%08x), pixels: %p\n", + surface->w, surface->h, surface->pitch, + surface->format->Rmask, surface->format->Gmask, + surface->format->Bmask, surface->format->Amask, + surface->pixels); return 0; error: @@ -1595,11 +2131,13 @@ static void DRM_FreeHWSurface_Accl(_THIS, GAL_Surface *surface) DrmVideoData* vdata = this->hidden; DrmSurfaceBuffer* surface_buffer; - surface_buffer = (DrmSurfaceBuffer*)surface->hwdata; - if (surface_buffer) { - if (surface_buffer->pixels) - vdata->driver_ops->unmap_buffer(vdata->driver, surface_buffer); - vdata->driver_ops->destroy_buffer(vdata->driver, surface_buffer); + if (vdata->driver) { + surface_buffer = (DrmSurfaceBuffer*)surface->hwdata; + if (surface_buffer) { + if (surface_buffer->buff) + vdata->driver_ops->unmap_buffer(vdata->driver, surface_buffer); + vdata->driver_ops->destroy_buffer(vdata->driver, surface_buffer); + } } surface->pixels = NULL; @@ -1616,7 +2154,12 @@ static int DRM_HWBlit(GAL_Surface *src, GAL_Rect *src_rc, src_buf = (DrmSurfaceBuffer*)src->hwdata; dst_buf = (DrmSurfaceBuffer*)dst->hwdata; - if ((src->flags & GAL_SRCALPHA) == GAL_SRCALPHA && + if ((src->flags & GAL_SRCPIXELALPHA) == GAL_SRCPIXELALPHA) { + return vdata->driver_ops->alpha_pixel_blit(vdata->driver, + src_buf, src_rc, dst_buf, dst_rc, + COLOR_BLEND_PD_SRC_OVER); + } + else if ((src->flags & GAL_SRCALPHA) == GAL_SRCALPHA && (src->flags & GAL_SRCCOLORKEY) == GAL_SRCCOLORKEY) { return vdata->driver_ops->alpha_key_blit(vdata->driver, src_buf, src_rc, dst_buf, dst_rc, @@ -1653,7 +2196,11 @@ static int DRM_CheckHWBlit_Accl(_THIS, GAL_Surface *src, GAL_Surface *dst) src->flags |= GAL_HWACCEL; /* Set the surface attributes */ - if ((src->flags & GAL_SRCALPHA) == GAL_SRCALPHA && + if ((src->flags & GAL_SRCPIXELALPHA) == GAL_SRCPIXELALPHA && + (vdata->driver_ops->alpha_pixel_blit == NULL)) { + src->flags &= ~GAL_HWACCEL; + } + else if ((src->flags & GAL_SRCALPHA) == GAL_SRCALPHA && (src->flags & GAL_SRCCOLORKEY) == GAL_SRCCOLORKEY && (vdata->driver_ops->alpha_key_blit == NULL)) { src->flags &= ~GAL_HWACCEL; @@ -1695,7 +2242,7 @@ static int DRM_FillHWRect_Accl(_THIS, GAL_Surface *dst, GAL_Rect *rect, return vdata->driver_ops->clear_buffer(vdata->driver, dst_buf, rect, color); } -static void DRM_UpdateRects_Accl (_THIS, int numrects, GAL_Rect *rects) +static void DRM_UpdateRects (_THIS, int numrects, GAL_Rect *rects) { DrmVideoData* vdata = this->hidden; @@ -1734,15 +2281,16 @@ BOOL __drm_get_surface_info (GAL_Surface *surface, DrmSurfaceInfo* info) DrmSurfaceBuffer* surface_buffer = (DrmSurfaceBuffer*)surface->hwdata; if (surface_buffer) { + info->handle = surface_buffer->handle; info->prime_fd = surface_buffer->prime_fd; info->name = surface_buffer->name; - info->handle = surface_buffer->handle; - info->id = surface_buffer->id; + info->fb_id = surface_buffer->fb_id; info->width = surface_buffer->width; info->height = surface_buffer->height; info->pitch = surface_buffer->pitch; info->drm_format = surface_buffer->drm_format; info->size = surface_buffer->size; + info->offset = surface_buffer->offset; return TRUE; } } @@ -1752,300 +2300,165 @@ BOOL __drm_get_surface_info (GAL_Surface *surface, DrmSurfaceInfo* info) /* called by drmCreateDCFromName */ GAL_Surface* __drm_create_surface_from_name (GHANDLE video, - uint32_t name, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch) + uint32_t name, uint32_t drm_format, uint32_t pixels_off, + uint32_t width, uint32_t height, uint32_t pitch) { GAL_VideoDevice *this = (GAL_VideoDevice *)video; DrmVideoData* vdata = this->hidden; DrmSurfaceBuffer* surface_buffer; - GAL_Surface* surface = NULL; Uint32 RGBAmasks[4]; - int depth; + int depth, cpp; if (this && this->VideoInit != DRM_VideoInit) { return NULL; } - if (vdata->driver_ops == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: not hardware accelerated!\n"); - return NULL; - } - - if (vdata->driver_ops->create_buffer_from_name == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: not implemented method: create_buffer_from_name!\n"); - return NULL; - } - - depth = translate_drm_format(drm_format, RGBAmasks); + depth = translate_drm_format(drm_format, RGBAmasks, &cpp); if (depth == 0) { - _ERR_PRINTF("NEWGAL>DRM: not supported drm format: %u\n", - drm_format); + _ERR_PRINTF("NEWGAL>DRM: not supported DRM format: %u\n", drm_format); return NULL; } - surface_buffer = vdata->driver_ops->create_buffer_from_name(vdata->driver, - name, drm_format, width, height, pitch); - if (surface_buffer == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: create_buffer_from_name failed!\n"); - return NULL; + if (vdata->driver == NULL || + vdata->driver_ops->create_buffer_from_name == NULL) { + surface_buffer = drm_create_dumb_buffer_from_name (vdata, name); + if (surface_buffer == NULL) { + _ERR_PRINTF ("NEWGAL>DRM: failed to create dumb buffer from name: " + "%u!\n", name); + return NULL; + } + surface_buffer->dumb = 1; } - /* not a foreign surface */ - surface_buffer->foreign = 0; - - if (vdata->driver_ops->map_buffer(vdata->driver, surface_buffer) == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: cannot map hardware buffer: %m\n"); - goto error; + else { + surface_buffer = vdata->driver_ops->create_buffer_from_name( + vdata->driver, name); + if (surface_buffer == NULL) { + _ERR_PRINTF ("NEWGAL>DRM: faile to create buffer from name: %u!\n", + name); + return NULL; + } + surface_buffer->dumb = 0; } - /* Allocate the surface */ - surface = (GAL_Surface *)malloc (sizeof(*surface)); - if (surface == NULL) { - goto error; - } + surface_buffer->fb_id = 0; + surface_buffer->drm_format = drm_format; + surface_buffer->bpp = depth; + surface_buffer->cpp = cpp; + surface_buffer->width = width; + surface_buffer->height = height; + surface_buffer->pitch = pitch; + surface_buffer->offset = pixels_off; - /* Allocate the format */ - surface->format = GAL_AllocFormat(depth, RGBAmasks[0], RGBAmasks[1], - RGBAmasks[2], RGBAmasks[3]); - if (surface->format == NULL) { - goto error; - } - - /* Allocate an empty mapping */ - surface->map = GAL_AllocBlitMap(); - if (surface->map == NULL) { - goto error; - } - - surface->format_version = 0; - surface->video = this; - surface->flags = GAL_HWSURFACE; - surface->dpi = GDCAP_DPI_DEFAULT; - surface->w = width; - surface->h = height; - surface->pitch = pitch; - surface->offset = 0; - surface->pixels = surface_buffer->pixels; - surface->hwdata = (struct private_hwdata *)surface_buffer; - - /* The surface is ready to go */ - surface->refcount = 1; - - GAL_SetClipRect(surface, NULL); - -#ifdef _MGUSE_SYNC_UPDATE - /* Initialize update region */ - InitClipRgn (&surface->update_region, &__mg_free_update_region_list); -#endif - - return(surface); - -error: - if (surface) - GAL_FreeSurface(surface); - - if (surface_buffer) - vdata->driver_ops->destroy_buffer(vdata->driver, surface_buffer); - - return NULL; + return create_surface_from_buffer (this, surface_buffer, depth, RGBAmasks); } /* called by drmCreateDCFromHandle */ -GAL_Surface* __drm_create_surface_from_handle (GHANDLE video, - uint32_t handle, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch) +GAL_Surface* __drm_create_surface_from_handle (GHANDLE video, uint32_t handle, + unsigned long size, uint32_t drm_format, uint32_t pixels_off, + uint32_t width, uint32_t height, uint32_t pitch) { GAL_VideoDevice *this = (GAL_VideoDevice *)video; DrmVideoData* vdata = this->hidden; DrmSurfaceBuffer* surface_buffer; - GAL_Surface* surface = NULL; Uint32 RGBAmasks[4]; - int depth; + int depth, cpp; if (this && this->VideoInit != DRM_VideoInit) { return NULL; } - if (vdata->driver_ops == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: not hardware accelerated!\n"); - return NULL; - } - - if (vdata->driver_ops->create_buffer_from_handle == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: not implemented method: create_buffer_from_handle!\n"); - return NULL; - } - - depth = translate_drm_format (drm_format, RGBAmasks); + depth = translate_drm_format (drm_format, RGBAmasks, &cpp); if (depth == 0) { - _ERR_PRINTF ("NEWGAL>DRM: not supported drm format: %u\n", - drm_format); + _ERR_PRINTF ("NEWGAL>DRM: not supported drm format: %u\n", drm_format); return NULL; } - surface_buffer = vdata->driver_ops->create_buffer_from_handle (vdata->driver, - handle, size, drm_format, width, height, pitch); - if (surface_buffer == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: create_buffer_from_handle failed!\n"); - return NULL; + if (vdata->driver == NULL || + vdata->driver_ops->create_buffer_from_handle == NULL) { + surface_buffer = drm_create_dumb_buffer_from_handle (vdata, + handle, size); + if (surface_buffer == NULL) { + _ERR_PRINTF ("NEWGAL>DRM: failed to create dumb buffer from handle " + "(%u): %m!\n", handle); + return NULL; + } + surface_buffer->dumb = 1; } - /* this is a foreign surface */ - surface_buffer->foreign = 1; - - if (vdata->driver_ops->map_buffer (vdata->driver, surface_buffer) == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: cannot map hardware buffer: %m\n"); - goto error; + else { + surface_buffer = vdata->driver_ops->create_buffer_from_handle ( + vdata->driver, handle, size); + if (surface_buffer == NULL) { + _ERR_PRINTF ("NEWGAL>DRM: failed to create buffer from handle (%u): " + "%m!\n", handle); + return NULL; + } + surface_buffer->dumb = 0; } - /* Allocate the surface */ - surface = (GAL_Surface *)malloc (sizeof(*surface)); - if (surface == NULL) { - goto error; - } + surface_buffer->fb_id = 0; + surface_buffer->drm_format = drm_format; + surface_buffer->bpp = depth; + surface_buffer->cpp = cpp; + surface_buffer->width = width; + surface_buffer->height = height; + surface_buffer->pitch = pitch; + surface_buffer->offset = pixels_off; - /* Allocate the format */ - surface->format = GAL_AllocFormat (depth, RGBAmasks[0], RGBAmasks[1], - RGBAmasks[2], RGBAmasks[3]); - if (surface->format == NULL) { - goto error; - } - - /* Allocate an empty mapping */ - surface->map = GAL_AllocBlitMap (); - if (surface->map == NULL) { - goto error; - } - - surface->format_version = 0; - surface->video = this; - surface->flags = GAL_HWSURFACE; - surface->dpi = GDCAP_DPI_DEFAULT; - surface->w = width; - surface->h = height; - surface->pitch = pitch; - surface->offset = 0; - surface->pixels = surface_buffer->pixels; - surface->hwdata = (struct private_hwdata *)surface_buffer; - - /* The surface is ready to go */ - surface->refcount = 1; - - GAL_SetClipRect(surface, NULL); - -#ifdef _MGUSE_SYNC_UPDATE - /* Initialize update region */ - InitClipRgn (&surface->update_region, &__mg_free_update_region_list); -#endif - - return(surface); - -error: - if (surface) - GAL_FreeSurface(surface); - - if (surface_buffer) - vdata->driver_ops->destroy_buffer(vdata->driver, surface_buffer); - - return NULL; + return create_surface_from_buffer (this, surface_buffer, depth, RGBAmasks); } /* called by drmCreateDCFromPrimeFd */ GAL_Surface* __drm_create_surface_from_prime_fd (GHANDLE video, - int prime_fd, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch) + int prime_fd, size_t size, uint32_t drm_format, uint32_t pixels_off, + uint32_t width, uint32_t height, uint32_t pitch) { GAL_VideoDevice *this = (GAL_VideoDevice *)video; DrmVideoData* vdata = this->hidden; DrmSurfaceBuffer* surface_buffer; - GAL_Surface* surface = NULL; Uint32 RGBAmasks[4]; - int depth; + int depth, cpp; if (this && this->VideoInit != DRM_VideoInit) { return NULL; } - if (vdata->driver_ops == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: not hardware accelerated!\n"); - return NULL; - } - - if (vdata->driver_ops->create_buffer_from_prime_fd == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: not implemented method: create_buffer_from_prime_fd.\n"); - return NULL; - } - - depth = translate_drm_format(drm_format, RGBAmasks); + depth = translate_drm_format(drm_format, RGBAmasks, &cpp); if (depth == 0) { _ERR_PRINTF("NEWGAL>DRM: not supported drm format: %u\n", drm_format); return NULL; } - surface_buffer = vdata->driver_ops->create_buffer_from_prime_fd (vdata->driver, - prime_fd, size, drm_format, width, height, pitch); - if (surface_buffer == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: create_buffer_from_prime_fd failed!\n"); - return NULL; + if (vdata->driver == NULL || + vdata->driver_ops->create_buffer_from_prime_fd == NULL) { + surface_buffer = drm_create_dumb_buffer_from_prime_fd (vdata, + prime_fd, size); + if (surface_buffer == NULL) { + _ERR_PRINTF ("NEWGAL>DRM: failed to create dumb buffer from prime " + "fd: %d!\n", prime_fd); + return NULL; + } } - /* not a foreign surface */ - surface_buffer->foreign = 1; - - if (vdata->driver_ops->map_buffer (vdata->driver, surface_buffer) == NULL) { - _ERR_PRINTF ("NEWGAL>DRM: cannot map hardware buffer: %m\n"); - goto error; + else { + surface_buffer = vdata->driver_ops->create_buffer_from_prime_fd ( + vdata->driver, prime_fd, size); + if (surface_buffer == NULL) { + _ERR_PRINTF ("NEWGAL>DRM: failed to create buffer from prime " + "fd: %d!\n", prime_fd); + return NULL; + } } - /* Allocate the surface */ - surface = (GAL_Surface *)malloc (sizeof(*surface)); - if (surface == NULL) { - goto error; - } + surface_buffer->fb_id = 0; + surface_buffer->drm_format = drm_format; + surface_buffer->bpp = depth; + surface_buffer->cpp = cpp; + surface_buffer->width = width; + surface_buffer->height = height; + surface_buffer->pitch = pitch; + surface_buffer->offset = pixels_off; - /* Allocate the format */ - surface->format = GAL_AllocFormat(depth, RGBAmasks[0], RGBAmasks[1], - RGBAmasks[2], RGBAmasks[3]); - if (surface->format == NULL) { - goto error; - } - - /* Allocate an empty mapping */ - surface->map = GAL_AllocBlitMap(); - if (surface->map == NULL) { - goto error; - } - - surface->format_version = 0; - surface->video = this; - surface->flags = GAL_HWSURFACE; - surface->dpi = GDCAP_DPI_DEFAULT; - surface->w = width; - surface->h = height; - surface->pitch = pitch; - surface->offset = 0; - surface->pixels = surface_buffer->pixels; - surface->hwdata = (struct private_hwdata *)surface_buffer; - - /* The surface is ready to go */ - surface->refcount = 1; - - GAL_SetClipRect(surface, NULL); - -#ifdef _MGUSE_SYNC_UPDATE - /* Initialize update region */ - InitClipRgn (&surface->update_region, &__mg_free_update_region_list); -#endif - - return(surface); - -error: - if (surface) - GAL_FreeSurface(surface); - - if (surface_buffer) - vdata->driver_ops->destroy_buffer(vdata->driver, surface_buffer); - - return NULL; + return create_surface_from_buffer (this, surface_buffer, depth, RGBAmasks); } #endif /* _MGGAL_DRM */ - diff --git a/src/newgal/drm/drmvideo.h b/src/newgal/drm/drmvideo.h index ff867876..7fd98357 100644 --- a/src/newgal/drm/drmvideo.h +++ b/src/newgal/drm/drmvideo.h @@ -15,7 +15,7 @@ * and Graphics User Interface (GUI) support system for embedded systems * and smart IoT devices. * - * Copyright (C) 2019, Beijing FMSoft Technologies Co., Ltd. + * Copyright (C) 2019 ~ 2020, Beijing FMSoft Technologies Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,13 +55,18 @@ /* Private display data */ -#define LEN_DEVICE_NAME 31 - typedef struct drm_mode_info DrmModeInfo; typedef struct GAL_PrivateVideoData { - char dev_name[LEN_DEVICE_NAME + 1]; + char* dev_name; + char* ex_driver; + GAL_Surface* real_screen; int dev_fd; + /* capabilities */ + uint32_t scanout_buff_id; + /* the global names of real screen and shadow screen */ + uint32_t real_name; + uint32_t cap_dumb:1; void* exdrv_handle; DrmDriverOps* driver_ops; @@ -70,23 +75,8 @@ typedef struct GAL_PrivateVideoData { DrmModeInfo* mode_list; GAL_Rect** modes; - int bpp; - uint32_t width; - uint32_t height; - uint32_t pitch; - uint32_t size; - - uint32_t scanout_buff_id; - uint8_t* scanout_fb; - DrmModeInfo* saved_info; drmModeCrtc* saved_crtc; - - /* only valid when using DUMB frame buffer */ - uint32_t handle; - - /* only valid when using DRM driver */ - uint32_t console_buff_id; } DrmVideoData; #endif /* _NEWGAL_DRIVIDEO_H */ diff --git a/src/newgal/newgal.c b/src/newgal/newgal.c index 307a4ed1..d05e3c77 100644 --- a/src/newgal/newgal.c +++ b/src/newgal/newgal.c @@ -87,12 +87,10 @@ BOOL GAL_ParseVideoMode (const char* mode, int* w, int* h, int* depth) return TRUE; } -int mg_InitGAL (void) +int mg_InitGAL (char* engine, char* mode) { int i; int w, h, depth; - char engine [LEN_ENGINE_NAME + 1]; - char mode [LEN_MODE + 1]; #if defined (WIN32) || !defined(__NOUNIX__) char* env_value; diff --git a/src/newgal/sysvideo.h b/src/newgal/sysvideo.h index 17453233..9ae350e2 100644 --- a/src/newgal/sysvideo.h +++ b/src/newgal/sysvideo.h @@ -102,10 +102,10 @@ struct GAL_VideoDevice { GAL_Surface *(*SetVideoMode)(_THIS, GAL_Surface *current, int width, int height, int bpp, Uint32 flags); +#if 0 /* Toggle the fullscreen mode */ int (*ToggleFullScreen)(_THIS, int on); -#if 0 /* This is called after the video mode has been set, to get the initial mouse state. It should queue events as necessary to properly represent the current mouse focus and position. @@ -141,6 +141,8 @@ struct GAL_VideoDevice { GAL_VideoInfo info; #ifndef _MGRM_THREADS + /* Copy video information to shared resource segment */ + void (*CopyVideoInfoToSharedRes)(_THIS); /* Request a surface in video memory */ void (*RequestHWSurface)(_THIS, const REQ_HWSURFACE* request, REP_HWSURFACE* reply); #endif diff --git a/src/newgal/video.c b/src/newgal/video.c index 676bad49..9e82116d 100644 --- a/src/newgal/video.c +++ b/src/newgal/video.c @@ -1406,3 +1406,15 @@ int GAL_SuspendVideo(void) return 0; } +#ifdef _MGRM_PROCESSES +BOOL GAL_CopyVideoInfoToSharedRes (void) +{ + if (__mg_current_video && __mg_current_video->CopyVideoInfoToSharedRes) { + __mg_current_video->CopyVideoInfoToSharedRes(__mg_current_video); + return TRUE; + } + + return FALSE; +} +#endif /* _MGRM_PROCESSES */ + diff --git a/src/newgdi/gdi.c b/src/newgdi/gdi.c index 0adcfdf0..72c29e10 100644 --- a/src/newgdi/gdi.c +++ b/src/newgdi/gdi.c @@ -3754,10 +3754,7 @@ MG_EXPORT GHANDLE GetVideoHandle (HDC hdc) #ifdef _MGGAL_DRM -/* implemented in DRI engine. */ -BOOL __drm_get_surface_info (GAL_Surface *surface, DrmSurfaceInfo* info); - -MG_EXPORT BOOL drmGetSurfaceInfo (GHANDLE video, HDC hdc, DrmSurfaceInfo* info) +BOOL drmGetSurfaceInfo (GHANDLE video, HDC hdc, DrmSurfaceInfo* info) { PDC pdc = dc_HDC2PDC (hdc); if (pdc->surface->video != (GHANDLE)video) @@ -3766,14 +3763,8 @@ MG_EXPORT BOOL drmGetSurfaceInfo (GHANDLE video, HDC hdc, DrmSurfaceInfo* info) return __drm_get_surface_info(pdc->surface, info); } -/* implemented in DRI engine. */ -GAL_Surface* __drm_create_surface_from_name (GHANDLE video, - uint32_t name, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch); - -MG_EXPORT HDC drmCreateDCFromName (GHANDLE video, - uint32_t name, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch) +HDC drmCreateDCFromNameEx (GHANDLE video, uint32_t name, uint32_t drm_format, + off_t offset, uint32_t width, uint32_t height, uint32_t pitch) { PDC pmem_dc = NULL; GAL_Surface* surface; @@ -3783,7 +3774,7 @@ MG_EXPORT HDC drmCreateDCFromName (GHANDLE video, LOCK (&__mg_gdilock); surface = __drm_create_surface_from_name (video, name, - drm_format, width, height, pitch); + drm_format, offset, width, height, pitch); UNLOCK (&__mg_gdilock); if (!surface) { @@ -3797,16 +3788,14 @@ MG_EXPORT HDC drmCreateDCFromName (GHANDLE video, pmem_dc->DataType = TYPE_HDC; pmem_dc->DCType = TYPE_MEMDC; - pmem_dc->inuse = TRUE; + pmem_dc->inuse = TRUE; pmem_dc->surface = surface; - dc_InitDC (pmem_dc, HWND_DESKTOP, FALSE); + dc_InitDC (pmem_dc, HWND_NULL, FALSE); InitClipRgn (&pmem_dc->lcrgn, &__mg_FreeClipRectList); MAKE_REGION_INFINITE(&pmem_dc->lcrgn); InitClipRgn (&pmem_dc->ecrgn, &__mg_FreeClipRectList); - pmem_dc->pGCRInfo = NULL; - pmem_dc->oldage = 0; pmem_dc->DevRC.left = 0; pmem_dc->DevRC.top = 0; @@ -3819,14 +3808,9 @@ MG_EXPORT HDC drmCreateDCFromName (GHANDLE video, return (HDC)pmem_dc; } -/* implemented in DRI engine. */ -GAL_Surface* __drm_create_surface_from_handle (GHANDLE video, - uint32_t handle, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch); - -MG_EXPORT HDC drmCreateDCFromHandle (GHANDLE video, - uint32_t handle, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch) +HDC drmCreateDCFromHandleEx (GHANDLE video, uint32_t handle, size_t size, + uint32_t drm_format, off_t offset, + uint32_t width, uint32_t height, uint32_t pitch) { PDC pmem_dc = NULL; GAL_Surface* surface; @@ -3836,7 +3820,7 @@ MG_EXPORT HDC drmCreateDCFromHandle (GHANDLE video, LOCK (&__mg_gdilock); surface = __drm_create_surface_from_handle (video, handle, size, - drm_format, width, height, pitch); + drm_format, offset, width, height, pitch); UNLOCK (&__mg_gdilock); if (!surface) { @@ -3850,16 +3834,14 @@ MG_EXPORT HDC drmCreateDCFromHandle (GHANDLE video, pmem_dc->DataType = TYPE_HDC; pmem_dc->DCType = TYPE_MEMDC; - pmem_dc->inuse = TRUE; + pmem_dc->inuse = TRUE; pmem_dc->surface = surface; - dc_InitDC (pmem_dc, HWND_DESKTOP, FALSE); + dc_InitDC (pmem_dc, HWND_NULL, FALSE); InitClipRgn (&pmem_dc->lcrgn, &__mg_FreeClipRectList); MAKE_REGION_INFINITE(&pmem_dc->lcrgn); InitClipRgn (&pmem_dc->ecrgn, &__mg_FreeClipRectList); - pmem_dc->pGCRInfo = NULL; - pmem_dc->oldage = 0; pmem_dc->DevRC.left = 0; pmem_dc->DevRC.top = 0; @@ -3872,14 +3854,9 @@ MG_EXPORT HDC drmCreateDCFromHandle (GHANDLE video, return (HDC)pmem_dc; } -/* implemented in DRI engine. */ -GAL_Surface* __drm_create_surface_from_prime_fd (GHANDLE video, - int prime_fd, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch); - -MG_EXPORT HDC drmCreateDCFromPrimeFd (GHANDLE video, - int prime_fd, unsigned long size, uint32_t drm_format, - unsigned int width, unsigned int height, uint32_t pitch) +HDC drmCreateDCFromPrimeFdEx (GHANDLE video, int prime_fd, size_t size, + uint32_t drm_format, off_t offset, + uint32_t width, uint32_t height, uint32_t pitch) { PDC pmem_dc = NULL; GAL_Surface* surface; @@ -3887,9 +3864,12 @@ MG_EXPORT HDC drmCreateDCFromPrimeFd (GHANDLE video, if (!(pmem_dc = malloc (sizeof(DC)))) return HDC_INVALID; + if (size == 0) { + } + LOCK (&__mg_gdilock); surface =__drm_create_surface_from_prime_fd (video, prime_fd, size, - drm_format, width, height, pitch); + drm_format, offset, width, height, pitch); UNLOCK (&__mg_gdilock); if (!surface) { @@ -3903,16 +3883,14 @@ MG_EXPORT HDC drmCreateDCFromPrimeFd (GHANDLE video, pmem_dc->DataType = TYPE_HDC; pmem_dc->DCType = TYPE_MEMDC; - pmem_dc->inuse = TRUE; + pmem_dc->inuse = TRUE; pmem_dc->surface = surface; - dc_InitDC (pmem_dc, HWND_DESKTOP, FALSE); + dc_InitDC (pmem_dc, HWND_NULL, FALSE); InitClipRgn (&pmem_dc->lcrgn, &__mg_FreeClipRectList); MAKE_REGION_INFINITE(&pmem_dc->lcrgn); InitClipRgn (&pmem_dc->ecrgn, &__mg_FreeClipRectList); - pmem_dc->pGCRInfo = NULL; - pmem_dc->oldage = 0; pmem_dc->DevRC.left = 0; pmem_dc->DevRC.top = 0; @@ -3925,4 +3903,4 @@ MG_EXPORT HDC drmCreateDCFromPrimeFd (GHANDLE video, return (HDC)pmem_dc; } -#endif +#endif /* _MGGAL_DRM */ diff --git a/src/server/request.c b/src/server/request.c index dd1a58c1..ee3e9d12 100644 --- a/src/server/request.c +++ b/src/server/request.c @@ -601,6 +601,34 @@ static int req_hw_surface (int cli, int clifd, void* buff, size_t len) extern int clipboard_op (int cli, int clifd, void* buff, size_t len); #endif +static int authenticate_client (int cli, int clifd, void* buff, size_t len) +{ + int auth_result = 1; + +#ifdef _MGGAL_DRM + uint32_t magic; + extern int __drm_auth_client(int, uint32_t); + magic = *(uint32_t*)buff; + auth_result = __drm_auth_client (cli, magic); +#endif + + return ServerSendReply (clifd, &auth_result, sizeof (int)); +} + +/* get the rendering surface */ +static int get_shared_surface (int cli, int clifd, void* buff, size_t len) +{ + SHAREDSURFINFO info = { 0, 0 }; + +#ifdef _MGGAL_DRM + const char* name = buff; + extern int __drm_get_shared_screen_surface (const char*, SHAREDSURFINFO*); + __drm_get_shared_screen_surface (name, &info); +#endif + + return ServerSendReply (clifd, &info, sizeof (SHAREDSURFINFO)); +} + static REQ_HANDLER handlers [MAX_REQID] = { load_cursor, @@ -646,6 +674,8 @@ static REQ_HANDLER handlers [MAX_REQID] = get_ime_targetinfo, set_ime_targetinfo, copy_cursor, + authenticate_client, + get_shared_surface, }; BOOL GUIAPI RegisterRequestHandler (int req_id, REQ_HANDLER your_handler)