debug APIs for shared surfaces

This commit is contained in:
Vincent Wei
2023-08-31 16:02:06 +08:00
parent 890ab1db44
commit fa18025350
14 changed files with 124 additions and 69 deletions
+1 -1
View File
@@ -62,7 +62,7 @@ dnl ========================================================================
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_DIRENT
AC_CHECK_HEADERS(limits.h math.h locale.h unistd.h termio.h sys/types.h sys/time.h sys/select.h sys/memfd.h)
AC_CHECK_HEADERS(limits.h math.h stdatomic.h locale.h unistd.h termio.h sys/types.h sys/time.h sys/select.h sys/memfd.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
+2
View File
@@ -268,6 +268,8 @@ MGUI_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8);
#define MG_UNLIKELY(expr) (expr)
#endif
#define HAVE(FEATURE) (defined HAVE_##FEATURE && HAVE_##FEATURE)
/**
* \defgroup endian_info Endianness information
* @{
+26 -15
View File
@@ -1884,26 +1884,22 @@ MG_EXPORT const char *GUIAPI GetSharedSurfaceInfo (HSURF surf, int *fd,
SIZE *size, int *pitch, size_t *map_size, off_t *pixels_off);
/**
* \fn BOOL GUIAPI LockSharedSurfaceIfDirty (HSURF surf,
* unsigned old_dirty_age, unsigned *dirty_age,
* int *nr_dirty_rects, const RECT **dirty_rects)
* \brief Locks the shared surface if it is dirty.
* \fn BOOL GUIAPI LockSharedSurface (HSURF surf,
* unsigned *dirty_age, int *nr_dirty_rects, const RECT **dirty_rects)
* \brief Locks the shared surface.
*
* This function compares the dirty age of the shared surface with the value
* containing in \a dirty_age, and lock the shared surface if it has
* a larger dirty age value.
* This function lock the given shared surface \a surf and returns
* the dirty age.
*
* \param surf The handle to the shared surface.
* \param old_dirty_age The old dirty age.
* \param dirty_age The pointer to a buffer of unsigned integer to return
* the current dirty age of the shared surface; NOT nullable.
* \param dirty_age The pointer to a buffer of unsigned integer to
* return the latest dirty age of the shared surface; nullable.
* \param nr_dirty_rects The pointer to a buffer of integer to return the valid
* dirty rectangles; nullable.
* \param dirty_rects The pointer to a buffer of (const RECT *) for the array
* of dirty rectangles; nullable.
*
* \return TRUE for success and if the value contains in \a dirty_age is not
* equal to \a old_dirty_age, the surface was locked; otherwise failure.
* \return 1 for locked; 0 for not locked; -1 for failure.
*
* \note This function only available when _MGSCHEMA_COMPOSITING is defined.
*
@@ -1911,9 +1907,8 @@ MG_EXPORT const char *GUIAPI GetSharedSurfaceInfo (HSURF surf, int *fd,
*
* Since 5.2.0
*/
MG_EXPORT BOOL GUIAPI LockSharedSurfaceIfDirty (HSURF surf,
unsigned old_dirty_age, unsigned *dirty_age,
int *nr_dirty_rects, const RECT **dirty_rects);
MG_EXPORT BOOL GUIAPI LockSharedSurface (HSURF surf,
unsigned *dirty_age, int *nr_dirty_rects, const RECT **dirty_rects);
/**
* \fn BOOL GUIAPI UnlockSharedSurface (HSURF surf, BOOL clear_dirty)
@@ -1972,6 +1967,22 @@ MG_EXPORT BOOL GUIAPI DetachFromSharedSurface (HSURF surf);
*/
MG_EXPORT HDC GUIAPI CreateMemDCFromSurface(HSURF surf);
/**
* \fn HSURF GUIAPI GetSurfaceFromDC(HDC hdc);
* \brief Gets surface handle from a DC.
*
* This function returns the handle to the surface of the given DC \a hdc.
*
* \param hdc The handle to the DC.
*
* \return The handle to the surface, NULL for failure.
*
* \sa CreateMemDCFromSurface
*
* Since 5.2.0
*/
MG_EXPORT HSURF GUIAPI GetSurfaceFromDC(HDC hdc);
/**
* \fn HDC GUIAPI CreateMemDCEx (int width, int height, int depth, DWORD flags, \
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask,
+3
View File
@@ -1222,6 +1222,9 @@ typedef struct _ZNODEHEADER {
int lock_count;
#ifdef _MGSCHEMA_COMPOSITING
/** The file descriptor of the surface; since 5.2.0. */
int fd;
/** The count for changes of the content. */
unsigned int changes;
/**
+4 -4
View File
@@ -4476,8 +4476,8 @@ HWND GUIAPI CreateMainWindowEx2 (PMAINWINCREATE pCreateInfo, LINT id,
#endif
#ifdef _MGSCHEMA_COMPOSITING
// Close file descriptor to free kernel memory?
if (pWin->surf->shared_header) {
/* Since 5.2.0: keep fd available. */
if (0 && pWin->surf->shared_header) {
close (pWin->surf->shared_header->fd);
pWin->surf->shared_header->fd = -1;
}
@@ -6036,8 +6036,8 @@ HWND GUIAPI CreateWindowEx2 (const char* spClassName,
}
#ifdef _MGSCHEMA_COMPOSITING
// Close file descriptor to free kernel memory?
if (dwExStyle & WS_EX_CTRLASMAINWIN && pNewCtrl->surf->shared_header) {
/* Since 5.2.0: keep fd available. */
if (0 && dwExStyle & WS_EX_CTRLASMAINWIN && pNewCtrl->surf->shared_header) {
close (pNewCtrl->surf->shared_header->fd);
pNewCtrl->surf->shared_header->fd = -1;
}
+7 -7
View File
@@ -142,19 +142,19 @@ typedef struct _SharedSurfaceHeader {
/* the name of the shared surface; since 5.2.0. */
char name[NAME_MAX + 1];
/* The pid of the creator */
pid_t creator;
/* the size of the whole buffer */
size_t map_size;
/* the offset of pixels data */
off_t pixels_off;
/* The client identifier of the creator. */
int create_cli;
/* The number of semphore for this surface.
The SysV semaphore set id for synchronizing this shared surface:
SHAREDRES_SEMID_SHARED_SURF. */
int sem_num;
/* the size of the whole buffer */
size_t map_size;
/* the offset of pixels data */
off_t pixels_off;
/* The file descriptor in context of the creator. */
int fd;
/* Not zero for hardware surface. */
+1
View File
@@ -79,6 +79,7 @@ typedef struct _ZORDERNODE {
unsigned int lock_count; /* the lock count */
#ifdef _MGSCHEMA_COMPOSITING
int fd; /* the file descriptor; since 5.2.0. */
unsigned int changes; /* count for changes of content */
int ct; /* the compositing type */
DWORD ct_arg; /* the argument for compositing */
+3 -3
View File
@@ -154,7 +154,7 @@ static int dskAllocZOrderNode (PMAINWIN pWin)
return AllocZOrderNode (0, (HWND)pWin,
(HWND)pWin->pMainWin,
get_znode_flags_from_style (pWin),
&rc, pWin->spCaption, HDC_INVALID,
&rc, pWin->spCaption, HDC_INVALID, -1,
CT_OPAQUE, 0);
}
@@ -588,7 +588,7 @@ static int dskMoveMainWindow (PMAINWIN pWin, const RECT* prcExpect)
SendAsyncMessage ((HWND)pWin, MSG_CHANGESIZE,
(WPARAM)(prcExpect), (LPARAM)(&rcResult));
return dskMoveWindow (0, pWin->idx_znode, HDC_INVALID, &rcResult);
return dskMoveWindow (0, pWin->idx_znode, HDC_INVALID, -1, &rcResult);
}
static int dskMoveGlobalControl (PMAINWIN pCtrl, RECT* prcExpect)
@@ -600,7 +600,7 @@ static int dskMoveGlobalControl (PMAINWIN pCtrl, RECT* prcExpect)
(WPARAM)(prcExpect), (LPARAM)(&rcResult));
dskClientToScreen ((PMAINWIN)(pCtrl->hParent), prcExpect, &newWinRect);
ret = dskMoveWindow (0, pCtrl->idx_znode, HDC_INVALID, &newWinRect);
ret = dskMoveWindow (0, pCtrl->idx_znode, HDC_INVALID, -1, &newWinRect);
if (ret == 0 && pCtrl->dwStyle & WS_VISIBLE) {
SendAsyncMessage ((HWND)pCtrl, MSG_NCPAINT, 0, 0);
+10 -7
View File
@@ -839,7 +839,8 @@ static int srvAllocZOrderNode (int cli, HWND hwnd, HWND main_win,
else if (fd >= 0) {
surf = GAL_AttachSharedRGBSurface (NULL, fd,
surf_size, surf_flags, TRUE);
close (fd);
/* Since 5.2.0: keep fd available.
close (fd); */
}
else {
_ERR_PRINTF("KERNEL: not server but fd for shared surface is invalid\n");
@@ -864,7 +865,7 @@ static int srvAllocZOrderNode (int cli, HWND hwnd, HWND main_win,
#endif /* def _MGSCHEMA_COMPOSITING */
free_slot = AllocZOrderNode (cli, hwnd,
main_win, flags, rc, caption, memdc, ct, ct_arg);
main_win, flags, rc, caption, memdc, fd, ct, ct_arg);
if ((free_slot != -1) && OnZNodeOperation)
OnZNodeOperation (ZNOP_ALLOCATE, cli, free_slot);
@@ -997,7 +998,8 @@ static int srvMoveWindow (int cli, int idx_znode, const RECT* rcWin,
else {
surf = GAL_AttachSharedRGBSurface (NULL, fd,
surf_size, surf_flags, TRUE);
close (fd);
/* Since 5.2.0: keep fd available.
close (fd); */
}
if (surf) {
@@ -1016,10 +1018,9 @@ static int srvMoveWindow (int cli, int idx_znode, const RECT* rcWin,
return -1;
}
}
#endif /* def _MGSCHEMA_COMPOSITING */
ret = dskMoveWindow (cli, idx_znode, memdc, rcWin);
ret = dskMoveWindow (cli, idx_znode, memdc, fd, rcWin);
if (ret == 0 && OnZNodeOperation)
OnZNodeOperation (ZNOP_MOVEWIN, cli, idx_znode);
@@ -2255,7 +2256,8 @@ static int dskMoveGlobalControl (PMAINWIN pCtrl, RECT* prcExpect)
}
#ifdef _MGSCHEMA_COMPOSITING
if (pCtrl->surf->shared_header && pCtrl->surf->shared_header->fd >= 0) {
/* Since 5.2.0: keep fd available. */
if (0 && pCtrl->surf->shared_header && pCtrl->surf->shared_header->fd >= 0) {
close (pCtrl->surf->shared_header->fd);
pCtrl->surf->shared_header->fd = -1;
}
@@ -2286,7 +2288,8 @@ static int dskMoveMainWindow (PMAINWIN pWin, RECT* prcExpect)
__mg_update_dc_on_surface_changed ((HWND)pWin, pWin->surf);
}
if (pWin->surf->shared_header && pWin->surf->shared_header->fd >= 0) {
/* Since 5.2.0: keep fd available. */
if (0 && pWin->surf->shared_header && pWin->surf->shared_header->fd >= 0) {
close (pWin->surf->shared_header->fd);
pWin->surf->shared_header->fd = -1;
}
+27 -5
View File
@@ -1535,6 +1535,10 @@ static int srvForceCloseMenu (int cli)
for (i = (zi->nr_popupmenus - 1); i >= 0; i--) {
DO_COMPSOR_OP_ARGS (on_hiding_ppp, i);
DeleteMemDC (menu_nodes[i].mem_dc);
/* Since 5.2.0 */
assert (menu_nodes[i].fd >= 0);
close (menu_nodes[i].fd);
menu_nodes[i].fd = -1;
}
#endif /* defined _MGSCHEMA_COMPOSITING */
@@ -1605,7 +1609,8 @@ static int srvStartTrackPopupMenu (int cli, const RECT* rc, HWND ptmi,
else if (fd >= 0) {
surf = GAL_AttachSharedRGBSurface (NULL, fd,
surf_size, surf_flags, TRUE);
close (fd);
/* Since 5.2.0: keep fd available.
close (fd); */
}
else {
_WRN_PRINTF("not server but fd for shared surface is invalid\n");
@@ -1648,6 +1653,7 @@ static int srvStartTrackPopupMenu (int cli, const RECT* rc, HWND ptmi,
menu_nodes [zi->nr_popupmenus].rc = *rc;
menu_nodes [zi->nr_popupmenus].hwnd = ptmi;
#ifdef _MGSCHEMA_COMPOSITING
menu_nodes [zi->nr_popupmenus].fd = fd;
menu_nodes [zi->nr_popupmenus].changes = 0;
menu_nodes [zi->nr_popupmenus].ct = CT_OPAQUE;
menu_nodes [zi->nr_popupmenus].ct_arg = 0;
@@ -1693,6 +1699,8 @@ static int srvEndTrackPopupMenu (int cli, int idx_znode)
#ifdef _MGSCHEMA_COMPOSITING
DO_COMPSOR_OP_ARGS (on_hiding_ppp, idx_znode);
close(menu_nodes [idx_znode].fd);
menu_nodes [idx_znode].fd = -1;
DeleteMemDC (menu_nodes [idx_znode].mem_dc);
#else /* not defined _MGSCHEMA_COMPOSITING */
rc = menu_nodes [idx_znode].rc;
@@ -2148,7 +2156,7 @@ static void update_on_new_visible_znode (void* layer, ZORDERINFO* zi,
static int AllocZOrderNodeEx (ZORDERINFO* zi, int cli, HWND hwnd, HWND main_win,
DWORD flags, const RECT *rc, const char *caption,
HDC mem_dc, int ct, DWORD ct_arg)
HDC mem_dc, int fd, int ct, DWORD ct_arg)
{
DWORD type = flags & ZOF_TYPE_MASK;
int *first = NULL, *nr_nodes = NULL;
@@ -2353,6 +2361,7 @@ static int AllocZOrderNodeEx (ZORDERINFO* zi, int cli, HWND hwnd, HWND main_win,
nodes [free_slot].main_win = main_win;
nodes [free_slot].lock_count = 0;
#ifdef _MGSCHEMA_COMPOSITING
nodes [free_slot].fd = fd;
nodes [free_slot].changes = 0;
nodes [free_slot].ct = validate_compositing_type (flags, ct);
nodes [free_slot].ct_arg = ct_arg;
@@ -2418,10 +2427,10 @@ static int AllocZOrderNodeEx (ZORDERINFO* zi, int cli, HWND hwnd, HWND main_win,
static inline int AllocZOrderNode (int cli, HWND hwnd, HWND main_win,
DWORD flags, const RECT *rc, const char *caption,
HDC mem_dc, int ct, DWORD ct_arg)
HDC mem_dc, int fd, int ct, DWORD ct_arg)
{
return AllocZOrderNodeEx (get_zorder_info(cli), cli, hwnd, main_win,
flags, rc, caption, mem_dc, ct, ct_arg);
flags, rc, caption, mem_dc, fd, ct, ct_arg);
}
static void prepare_to_delete_visible_znode (void* layer, ZORDERINFO* zi,
@@ -2568,6 +2577,14 @@ static int FreeZOrderNodeEx (ZORDERINFO* zi, int idx_znode, HDC* memdc)
nodes[idx_znode].caption = NULL;
}
#ifdef _MGSCHEMA_COMPOSITING
/* Since 5.2.0 */
if (nodes[idx_znode].fd >= 0) {
close(nodes[idx_znode].fd);
nodes[idx_znode].fd = -1;
}
#endif
/* Free mask rects */
if (nodes[idx_znode].idx_mask_rect) {
release_znode_maskrect (nodes, idx_znode);
@@ -3361,7 +3378,8 @@ static int dskHideWindow (int cli, int idx_znode)
return 0;
}
static int dskMoveWindow (int cli, int idx_znode, HDC memdc, const RECT* rcWin)
static int dskMoveWindow (int cli, int idx_znode, HDC memdc, int fd,
const RECT* rcWin)
{
DWORD type;
int level, *first = NULL;
@@ -3710,6 +3728,10 @@ static int dskMoveWindow (int cli, int idx_znode, HDC memdc, const RECT* rcWin)
if (memdc != HDC_INVALID) {
DeleteMemDC (nodes [idx_znode].mem_dc);
nodes [idx_znode].mem_dc = memdc;
/* Since 5.2.0 */
assert (nodes [idx_znode].fd >= 0);
close (nodes [idx_znode].fd);
nodes [idx_znode].fd = fd;
}
unlock_zi_for_change (zi);
+3 -2
View File
@@ -59,6 +59,7 @@
#include <sys/mman.h>
#include <unistd.h>
#include "internals.h"
#include "misc.h"
#include "newgal.h"
#include "sysvideo.h"
@@ -203,7 +204,7 @@ GAL_Surface *GAL_CreateSharedRGBSurface (GAL_VideoDevice *video,
/* fill fileds of shared header */
memset (hdr, 0, sizeof(GAL_SharedSurfaceHeader));
hdr->creator = getpid();
hdr->create_cli = __mg_client_id;
hdr->fd = fd;
hdr->byhw = byhw;
hdr->width = surface->w;
@@ -387,7 +388,7 @@ GAL_Surface * GAL_AttachSharedRGBSurface (GAL_VideoDevice *video,
data_map = mmap (NULL, map_size, prot, MAP_SHARED, fd, 0);
if (data_map == MAP_FAILED) {
_ERR_PRINTF("NEWGAL: Failed to map shared RGB surface: %d\n", fd);
_ERR_PRINTF("NEWGAL: Failed to map shared RGB surface: %d (%m)\n", fd);
goto error;
}
+6 -3
View File
@@ -3384,11 +3384,14 @@ HDC GUIAPI CreateMemDCFromSurface (HSURF surface)
return (HDC)pmem_dc;
}
struct GAL_Surface* GetSurfaceFromDC (HDC hdc)
HSURF GUIAPI GetSurfaceFromDC (HDC hdc)
{
PDC pdc;
pdc = dc_HDC2PDC (hdc);
return pdc->surface;
pdc = dc_HDC2PDC(hdc);
if (pdc)
return pdc->surface;
return NULL;
}
HDC GUIAPI CreateSubMemDC (HDC parent, int off_x, int off_y,
+23 -18
View File
@@ -175,7 +175,7 @@ BOOL GUIAPI DestroySharedSurface(HSURF surf)
goto failed;
}
if (surf->shared_header->creator != getpid()) {
if (surf->shared_header->create_cli != __mg_client_id) {
_ERR_PRINTF("INVALID_CALL: surface is not created by current process: %p\n", surf);
goto failed;
}
@@ -290,7 +290,12 @@ int GUIAPI GetSharedSurfaceFDByName(const char *name,
HSURF GUIAPI AttachToSharedSurface(GHANDLE video, int fd,
size_t map_size, DWORD flags)
{
return GAL_AttachSharedRGBSurface(video, fd, map_size, flags, TRUE);
HSURF surf = GAL_AttachSharedRGBSurface(video, fd, map_size, flags, TRUE);
if (surf) {
surf->refcount++;
}
return surf;
}
const char *GUIAPI GetSharedSurfaceInfo(HSURF surf, int *fd,
@@ -328,8 +333,7 @@ failed:
return NULL;
}
BOOL GUIAPI LockSharedSurfaceIfDirty(HSURF surf,
unsigned old_dirty_age, unsigned *dirty_age,
BOOL GUIAPI LockSharedSurface(HSURF surf, unsigned *dirty_age,
int *nr_dirty_rcs, const RECT **dirty_rcs)
{
if (surf->shared_header == NULL) {
@@ -338,23 +342,23 @@ BOOL GUIAPI LockSharedSurfaceIfDirty(HSURF surf,
}
if (surf->flags & GAL_SSURF_LOCKED) {
_ERR_PRINTF("INVALID_CALL: surface locked: %p\n", surf);
_WRN_PRINTF("INVALID_CALL: surface locked: %p\n", surf);
goto failed;
}
/* FIXME: use atomic types */
if (old_dirty_age != surf->shared_header->dirty_info.dirty_age) {
LOCK_SURFACE_SEM(surf->shared_header->sem_num);
LOCK_SURFACE_SEM(surf->shared_header->sem_num);
surf->flags |= GAL_SSURF_LOCKED;
surf->flags |= GAL_SSURF_LOCKED;
if (dirty_age) {
*dirty_age = surf->shared_header->dirty_info.dirty_age;
if (nr_dirty_rcs) {
*nr_dirty_rcs = surf->shared_header->dirty_info.nr_dirty_rcs;
}
}
if (dirty_rcs) {
*dirty_rcs = surf->shared_header->dirty_info.dirty_rcs;
}
if (nr_dirty_rcs) {
*nr_dirty_rcs = surf->shared_header->dirty_info.nr_dirty_rcs;
}
if (dirty_rcs) {
*dirty_rcs = surf->shared_header->dirty_info.dirty_rcs;
}
return TRUE;
@@ -371,16 +375,17 @@ BOOL GUIAPI UnlockSharedSurface(HSURF surf, BOOL clear_dirty)
}
if (!(surf->flags & GAL_SSURF_LOCKED)) {
_ERR_PRINTF("INVALID_CALL: surface is not locked: %p\n", surf);
_WRN_PRINTF("INVALID_CALL: surface not locked: %p\n", surf);
goto failed;
}
UNLOCK_SURFACE_SEM(surf->shared_header->sem_num);
surf->flags &= ~GAL_SSURF_LOCKED;
if (clear_dirty) {
surf->dirty_info->nr_dirty_rcs = 0;
}
UNLOCK_SURFACE_SEM(surf->shared_header->sem_num);
surf->flags &= ~GAL_SSURF_LOCKED;
return TRUE;
failed:
+8 -4
View File
@@ -55,7 +55,6 @@
#include <signal.h>
#define _DEBUG
#include "common.h"
#include "minigui.h"
#include "gdi.h"
@@ -869,6 +868,7 @@ int __mg_nssurf_map_operate_srv(const OPERATENSSURFINFO* req_info,
nssurf_info->fd = fd;
nssurf_info->map_size = req_info->map_size;
_DBG_PRINTF("fd set for named ssurf %s: %d\n", req_info->name, fd);
result = 0;
break;
@@ -909,8 +909,10 @@ int __mg_get_shared_surface_srv(const char *itn_name, SHAREDSURFINFO *info)
sizeof(APPSF_NAME_PREFIX) - 1) == 0) {
const char *name = itn_name + sizeof(APPSF_NAME_PREFIX) - 1;
map_entry_t *entry = __mg_map_find(__nssurf_map, name);
if (entry == NULL)
if (entry == NULL) {
_DBG_PRINTF("Not found named ssurf: %s\n", name);
goto done;
}
struct nssurf_info *nssurf_info = entry->val;
assert(nssurf_info);
@@ -922,8 +924,10 @@ int __mg_get_shared_surface_srv(const char *itn_name, SHAREDSURFINFO *info)
int client;
HWND hwnd;
int ret = sscanf(itn_name, APPSF_HWND_PATTER, &client, &hwnd);
if (ret != 2)
if (ret != 2) {
_WRN_PRINTF("Failed sscanf: %s\n", itn_name);
goto done;
}
ZORDERNODE *znode = __mg_find_znode_by_client_hwnd(client, hwnd);
if (znode == NULL)
@@ -936,7 +940,7 @@ int __mg_get_shared_surface_srv(const char *itn_name, SHAREDSURFINFO *info)
info->height = pdc->surface->shared_header->height;
info->pitch = pdc->surface->shared_header->pitch;
info->offset = pdc->surface->shared_header->pixels_off;
fd = pdc->surface->shared_header->fd;
fd = znode->fd;
}
done: