Add OnBeforeUpdate() and OnAfterUpdate() operations for Shadow engine

This commit is contained in:
Vincent Wei
2023-07-27 10:46:58 +08:00
parent 39d03be6d7
commit fcde9eb405
4 changed files with 109 additions and 57 deletions

View File

@@ -127,6 +127,8 @@ static void DRM_UpdateRects(_THIS, int numrects, GAL_Rect *rects);
static BOOL DRM_WaitVBlank(_THIS);
static BOOL DRM_SyncUpdate(_THIS);
static BOOL DRM_SyncUpdateAsync(_THIS);
static void DRM_OnBeforeUpdate(_THIS);
static void DRM_OnAfterUpdate(_THIS);
#if IS_SHAREDFB_SCHEMA_PROCS
/* DRM engine methods for clients under sharedfb schema and MiniGUI-Processes */
@@ -2426,25 +2428,75 @@ static void update_real_screen_memcpy(_THIS)
}
}
static void drm_dmabuf_start(DrmSurfaceBuffer *real_buff)
static void DRM_OnBeforeUpdate(_THIS)
{
struct dma_buf_sync sync;
DrmVideoData *vdata = this->hidden;
DrmSurfaceBuffer *real_buff;
real_buff = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;;
sync.flags = DMA_BUF_SYNC_WRITE | DMA_BUF_SYNC_START;
if (ioctl(real_buff->prime_fd, DMA_BUF_IOCTL_SYNC, &sync)) {
_WRN_PRINTF("Failed ioctl(DMA_BUF_IOCTL_SYNC): %m\n");
if (vdata->dirty_fb_ok == 0 &&
real_buff->prime_fd >= 0 && real_buff->dma_buff) {
struct dma_buf_sync sync;
sync.flags = DMA_BUF_SYNC_WRITE | DMA_BUF_SYNC_START;
if (ioctl(real_buff->prime_fd, DMA_BUF_IOCTL_SYNC, &sync)) {
_WRN_PRINTF("Failed ioctl(DMA_BUF_IOCTL_SYNC): %m\n");
}
}
}
static void drm_dmabuf_end(DrmSurfaceBuffer *real_buff)
static void DRM_OnAfterUpdate(_THIS)
{
struct dma_buf_sync sync;
sync.flags = DMA_BUF_SYNC_WRITE | DMA_BUF_SYNC_END;
if (ioctl(real_buff->prime_fd, DMA_BUF_IOCTL_SYNC, &sync)) {
_WRN_PRINTF("Failed ioctl(DMA_BUF_IOCTL_SYNC): %m\n");
DrmVideoData *vdata = this->hidden;
DrmSurfaceBuffer *real_buff;
real_buff = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;;
if (vdata->dirty_fb_ok == 0 &&
real_buff->prime_fd >= 0 && real_buff->dma_buff) {
struct dma_buf_sync sync;
sync.flags = DMA_BUF_SYNC_WRITE | DMA_BUF_SYNC_END;
if (ioctl(real_buff->prime_fd, DMA_BUF_IOCTL_SYNC, &sync)) {
_WRN_PRINTF("Failed ioctl(DMA_BUF_IOCTL_SYNC): %m\n");
}
}
}
#ifdef _MGSCHEMA_COMPOSITING
static void refresh_cursor(_THIS)
{
if (this->hidden->cursor && !this->hidden->cursor_buff) {
RECT csr_rc, eff_rc;
csr_rc.left = boxleft (this);
csr_rc.top = boxtop (this);
csr_rc.right = csr_rc.left + CURSORWIDTH;
csr_rc.bottom = csr_rc.top + CURSORHEIGHT;
if (IntersectRect (&eff_rc, &csr_rc, &bound)) {
GAL_Rect src_rect, dst_rect;
src_rect.x = eff_rc.left - csr_rc.left;
src_rect.y = eff_rc.top - csr_rc.top;
src_rect.w = RECTW (eff_rc);
src_rect.h = RECTH (eff_rc);
dst_rect.x = eff_rc.left;
dst_rect.y = eff_rc.top;
dst_rect.w = src_rect.w;
dst_rect.h = src_rect.h;
GAL_SetupBlitting (this->hidden->cursor,
this->hidden->real_screen, 0);
GAL_BlitSurface (this->hidden->cursor, &src_rect,
this->hidden->real_screen, &dst_rect);
GAL_CleanupBlitting (this->hidden->cursor,
this->hidden->real_screen);
}
}
}
#else
static inline void refresh_cursor(_THIS) {
(void)this;
}
#endif /* _MGSCHEMA_COMPOSITING */
static void update_real_screen_helper(_THIS)
{
DrmVideoData* vdata = this->hidden;
@@ -2462,9 +2514,6 @@ static void update_real_screen_helper(_THIS)
clock_gettime(CLOCK_REALTIME, &ts_start);
#endif
if (real_buff->prime_fd >= 0 && real_buff->dma_buff)
drm_dmabuf_start(real_buff);
BOOL hw_ok = FALSE;
if (shadow_buff && vdata->driver && vdata->driver_ops->copy_buff) {
GAL_Rect rect = {
@@ -2485,8 +2534,7 @@ static void update_real_screen_helper(_THIS)
update_real_screen_memcpy(this);
}
if (real_buff->prime_fd >= 0 && real_buff->dma_buff)
drm_dmabuf_end(real_buff);
refresh_cursor(this);
#if 0 // def _DEBUG
double elapsed = get_elapsed_seconds(&ts_start, NULL);
@@ -2547,17 +2595,19 @@ static void* task_do_update(void *data)
sem_wait(this->hidden->update_lock);
if (RECTH(this->hidden->update_rect)) {
DRM_OnBeforeUpdate(this);
update_real_screen_helper(this);
/* TODO: update cursor under compositing schema */
drmModeClip clip = {
this->hidden->update_rect.left,
this->hidden->update_rect.top,
this->hidden->update_rect.right,
this->hidden->update_rect.bottom };
DRM_OnAfterUpdate(this);
if (drmModeDirtyFB(this->hidden->dev_fd,
this->hidden->scanout_buff_id, &clip, 1)) {
_WRN_PRINTF("Failed drmModeDirtyFB: %m\n");
if (this->hidden->dirty_fb_ok) {
drmModeClip clip = {
this->hidden->update_rect.left,
this->hidden->update_rect.top,
this->hidden->update_rect.right,
this->hidden->update_rect.bottom };
drmModeDirtyFB(this->hidden->dev_fd,
this->hidden->scanout_buff_id, &clip, 1);
}
SetRectEmpty(&this->hidden->update_rect);
@@ -2789,6 +2839,16 @@ static GAL_Surface *DRM_SetVideoMode(_THIS, GAL_Surface *current,
#endif /* IS_COMPOSITING_SCHEMA */
GAL_FreeSurface (current);
drmModeClip clip = { 0, 0, 1, 1 };
if (drmModeDirtyFB(vdata->dev_fd,
vdata->scanout_buff_id, &clip, 1) == 0) {
vdata->dirty_fb_ok = 1;
}
else {
_WRN_PRINTF("Failed drmModeDirtyFB: %m\n");
}
if (vdata->shadow_screen) {
if (create_async_updater(this) == 0) {
vdata->shadow_screen->flags |= GAL_ASYNCBLIT;
@@ -2799,6 +2859,10 @@ static GAL_Surface *DRM_SetVideoMode(_THIS, GAL_Surface *current,
return vdata->shadow_screen;
}
else if (vdata->dirty_fb_ok == 0) {
this->OnBeforeUpdate = DRM_OnBeforeUpdate;
this->OnAfterUpdate = DRM_OnAfterUpdate;
}
return vdata->real_screen;
@@ -3717,7 +3781,7 @@ static BOOL DRM_SyncUpdate(_THIS)
#ifndef _MGSCHEMA_COMPOSITING
if (this->hidden->dbl_buff && this->hidden->update_lock != SEM_FAILED) {
sem_wait (this->hidden->update_lock);
sem_wait(this->hidden->update_lock);
}
#endif
@@ -3743,46 +3807,20 @@ static BOOL DRM_SyncUpdate(_THIS)
bound = *dirty_rc;
if (this->hidden->shadow_screen) {
DRM_OnBeforeUpdate(this);
update_real_screen_helper(this);
DRM_OnAfterUpdate(this);
}
#ifdef _MGSCHEMA_COMPOSITING
if (this->hidden->cursor && !this->hidden->cursor_buff) {
RECT csr_rc, eff_rc;
csr_rc.left = boxleft (this);
csr_rc.top = boxtop (this);
csr_rc.right = csr_rc.left + CURSORWIDTH;
csr_rc.bottom = csr_rc.top + CURSORHEIGHT;
if (IntersectRect (&eff_rc, &csr_rc, &bound)) {
GAL_Rect src_rect, dst_rect;
src_rect.x = eff_rc.left - csr_rc.left;
src_rect.y = eff_rc.top - csr_rc.top;
src_rect.w = RECTW (eff_rc);
src_rect.h = RECTH (eff_rc);
dst_rect.x = eff_rc.left;
dst_rect.y = eff_rc.top;
dst_rect.w = src_rect.w;
dst_rect.h = src_rect.h;
GAL_SetupBlitting (this->hidden->cursor,
this->hidden->real_screen, 0);
GAL_BlitSurface (this->hidden->cursor, &src_rect,
this->hidden->real_screen, &dst_rect);
GAL_CleanupBlitting (this->hidden->cursor,
this->hidden->real_screen);
}
}
#endif /* _MGSCHEMA_COMPOSITING */
refresh_cursor(this);
if (this->hidden->driver && this->hidden->driver_ops->flush_driver) {
this->hidden->driver_ops->flush_driver(this->hidden->driver);
}
{
if (this->hidden->dirty_fb_ok) {
drmModeClip clip = { bound.left, bound.top,
bound.right, bound.bottom };
drmModeDirtyFB(this->hidden->dev_fd,
this->hidden->scanout_buff_id, &clip, 1);
}

View File

@@ -103,6 +103,7 @@ typedef struct GAL_PrivateVideoData {
uint32_t cap_dumb:1;
uint32_t cap_vblank_high_crtc:1;
uint32_t dbl_buff:1;
uint32_t dirty_fb_ok:1;
uint32_t scanout_buff_id;
int crtc_idx;

View File

@@ -677,12 +677,12 @@ update_helper(_THIS, GAL_VideoDevice *real_device, RECT *update_rect)
else if (this->hidden->realfb_info->flags & _ROT_DIR_HFLIP) {
op = BLIT_COPY_FLIP_H;
dirty_rect = *update_rect;
_get_dst_rect_hflip (&dirty_rect, this->hidden->realfb_info);
_get_dst_rect_hflip(&dirty_rect, this->hidden->realfb_info);
}
else if (this->hidden->realfb_info->flags & _ROT_DIR_VFLIP) {
op = BLIT_COPY_FLIP_V;
dirty_rect = *update_rect;
_get_dst_rect_vflip (&dirty_rect, this->hidden->realfb_info);
_get_dst_rect_vflip(&dirty_rect, this->hidden->realfb_info);
}
else {
dirty_rect = *update_rect;
@@ -694,6 +694,9 @@ update_helper(_THIS, GAL_VideoDevice *real_device, RECT *update_rect)
dst_rc.w = RECTW(dirty_rect);
dst_rc.h = RECTH(dirty_rect);
if (real_device->OnBeforeUpdate)
real_device->OnBeforeUpdate(real_device);
BOOL hw_ok = FALSE;
if ((dst_rc.w * dst_rc.h) >= this->hidden->min_pixels_using_hwaccl) {
if (real_device->CopyHWSurface) {
@@ -718,6 +721,8 @@ update_helper(_THIS, GAL_VideoDevice *real_device, RECT *update_rect)
real_device->UpdateRects(real_device, 1, &dst_rc);
if (real_device->SyncUpdate)
real_device->SyncUpdate(real_device);
if (real_device->OnAfterUpdate)
real_device->OnAfterUpdate(real_device);
SetRectEmpty(update_rect);
}

View File

@@ -131,9 +131,17 @@ struct GAL_VideoDevice {
/* Wait vertical blank */
BOOL (*WaitVBlank)(_THIS);
/* Shadow engine will call this before updating the dirty content
if it is not NULL. */
void (*OnBeforeUpdate)(_THIS);
/* Synchronize the dirty content */
BOOL (*SyncUpdate)(_THIS);
/* Shadow engine will call this after updating the dirty content
if it is not NULL. */
void (*OnAfterUpdate)(_THIS);
/* Reverse the effects VideoInit() -- called if VideoInit() fails
or if the application is shutting down the video subsystem.
*/