From 5672f48fc04b95e7468f152508d7b356dda5e7db Mon Sep 17 00:00:00 2001
|
From: Hertz Wang <wangh@rock-chips.com>
|
Date: Fri, 16 Nov 2018 17:03:43 +0800
|
Subject: [PATCH] force display of video on overlay plane
|
|
note: control the video display layer according
|
to the SDL2_DISPLAY_PLANE_TYPE environment variable
|
|
Signed-off-by: Hertz Wang <wangh@rock-chips.com>
|
---
|
src/video/kmsdrm/SDL_kmsdrmopengles.c | 62 +++++++++++++++-----------
|
src/video/kmsdrm/SDL_kmsdrmsym.h | 18 +++++++-
|
src/video/kmsdrm/SDL_kmsdrmvideo.c | 83 ++++++++++++++++++++++++++++++++++-
|
src/video/kmsdrm/SDL_kmsdrmvideo.h | 2 +
|
4 files changed, 136 insertions(+), 29 deletions(-)
|
|
diff --git a/src/video/kmsdrm/SDL_kmsdrmopengles.c b/src/video/kmsdrm/SDL_kmsdrmopengles.c
|
index 7ba663f..ff0ce6c 100644
|
--- a/src/video/kmsdrm/SDL_kmsdrmopengles.c
|
+++ b/src/video/kmsdrm/SDL_kmsdrmopengles.c
|
@@ -140,36 +140,46 @@ KMSDRM_GLES_SwapWindow(_THIS, SDL_Window * window) {
|
if (fb_info == NULL) {
|
return 0;
|
}
|
- if (_this->egl_data->egl_swapinterval == 0) {
|
- /* Swap buffers instantly, possible tearing */
|
- /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModeSetCrtc(%d, %u, %u, 0, 0, &%u, 1, &%ux%u@%u)",
|
+
|
+ if (!wdata->plane_id) {
|
+ if (_this->egl_data->egl_swapinterval == 0) {
|
+ /* Swap buffers instantly, possible tearing */
|
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModeSetCrtc(%d, %u, %u, 0, 0, &%u, 1, &%ux%u@%u)",
|
vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id, vdata->saved_conn_id,
|
displaydata->cur_mode.hdisplay, displaydata->cur_mode.vdisplay, displaydata->cur_mode.vrefresh); */
|
- ret = KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
|
- 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode);
|
- if(ret != 0) {
|
- SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not pageflip with drmModeSetCrtc: %d", ret);
|
+ ret = KMSDRM_drmModeSetCrtc(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
|
+ 0, 0, &vdata->saved_conn_id, 1, &displaydata->cur_mode);
|
+ if(ret != 0) {
|
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not pageflip with drmModeSetCrtc: %d", ret);
|
+ }
|
+ } else {
|
+ /* Queue page flip at vsync */
|
+
|
+ /* Have we already setup the CRTC to one of the GBM buffers? Do so if we have not,
|
+ or FlipPage won't work in some cases. */
|
+ if (!wdata->crtc_ready) {
|
+ if(!KMSDRM_GLES_SetupCrtc(_this, window)) {
|
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC for doing vsync-ed pageflips");
|
+ return 0;
|
+ }
|
+ }
|
+
|
+ /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip)",
|
+ vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */
|
+ ret = KMSDRM_drmModePageFlip(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
|
+ DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip);
|
+ if (ret == 0) {
|
+ wdata->waiting_for_flip = SDL_TRUE;
|
+ } else {
|
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
|
+ }
|
}
|
} else {
|
- /* Queue page flip at vsync */
|
-
|
- /* Have we already setup the CRTC to one of the GBM buffers? Do so if we have not,
|
- or FlipPage won't work in some cases. */
|
- if (!wdata->crtc_ready) {
|
- if(!KMSDRM_GLES_SetupCrtc(_this, window)) {
|
- SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not set up CRTC for doing vsync-ed pageflips");
|
- return 0;
|
- }
|
- }
|
-
|
- /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "drmModePageFlip(%d, %u, %u, DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip)",
|
- vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id); */
|
- ret = KMSDRM_drmModePageFlip(vdata->drm_fd, displaydata->crtc_id, fb_info->fb_id,
|
- DRM_MODE_PAGE_FLIP_EVENT, &wdata->waiting_for_flip);
|
- if (ret == 0) {
|
- wdata->waiting_for_flip = SDL_TRUE;
|
- } else {
|
- SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not queue pageflip: %d", ret);
|
+ ret = KMSDRM_drmModeSetPlane(vdata->drm_fd, wdata->plane_id, displaydata->crtc_id, fb_info->fb_id,
|
+ 0, 0, 0, displaydata->cur_mode.hdisplay, displaydata->cur_mode.vdisplay,
|
+ 0, 0, KMSDRM_gbm_bo_get_width(wdata->next_bo) << 16, KMSDRM_gbm_bo_get_height(wdata->next_bo) << 16);
|
+ if(ret != 0) {
|
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Could not drmModeSetPlane: %d", ret);
|
}
|
}
|
|
diff --git a/src/video/kmsdrm/SDL_kmsdrmsym.h b/src/video/kmsdrm/SDL_kmsdrmsym.h
|
index 72c07a9..87e9397 100644
|
--- a/src/video/kmsdrm/SDL_kmsdrmsym.h
|
+++ b/src/video/kmsdrm/SDL_kmsdrmsym.h
|
@@ -40,13 +40,23 @@ SDL_KMSDRM_SYM(void,drmModeFreeFB,(drmModeFBPtr ptr))
|
SDL_KMSDRM_SYM(void,drmModeFreeCrtc,(drmModeCrtcPtr ptr))
|
SDL_KMSDRM_SYM(void,drmModeFreeConnector,(drmModeConnectorPtr ptr))
|
SDL_KMSDRM_SYM(void,drmModeFreeEncoder,(drmModeEncoderPtr ptr))
|
+SDL_KMSDRM_SYM(void,drmModeFreePlane,(drmModePlanePtr ptr))
|
+SDL_KMSDRM_SYM(void,drmModeFreePlaneResources,(drmModePlaneResPtr ptr))
|
+SDL_KMSDRM_SYM(void,drmModeFreeProperty,(drmModePropertyPtr ptr))
|
+SDL_KMSDRM_SYM(void,drmModeFreeObjectProperties,(drmModeObjectPropertiesPtr ptr))
|
+
|
SDL_KMSDRM_SYM(drmModeResPtr,drmModeGetResources,(int fd))
|
+SDL_KMSDRM_SYM(drmModePlaneResPtr,drmModeGetPlaneResources,(int fd))
|
SDL_KMSDRM_SYM(int,drmModeAddFB,(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
|
uint32_t *buf_id))
|
SDL_KMSDRM_SYM(int,drmModeRmFB,(int fd, uint32_t bufferId))
|
SDL_KMSDRM_SYM(drmModeFBPtr,drmModeGetFB,(int fd, uint32_t buf))
|
SDL_KMSDRM_SYM(drmModeCrtcPtr,drmModeGetCrtc,(int fd, uint32_t crtcId))
|
+SDL_KMSDRM_SYM(drmModePlanePtr,drmModeGetPlane,(int fd, uint32_t plane_id))
|
+SDL_KMSDRM_SYM(drmModePropertyPtr,drmModeGetProperty,(int fd, uint32_t propertyId))
|
+SDL_KMSDRM_SYM(drmModeObjectPropertiesPtr,drmModeObjectGetProperties,
|
+ (int fd, uint32_t object_id, uint32_t object_type))
|
SDL_KMSDRM_SYM(int,drmModeSetCrtc,(int fd, uint32_t crtcId, uint32_t bufferId,
|
uint32_t x, uint32_t y, uint32_t *connectors, int count,
|
drmModeModeInfoPtr mode))
|
@@ -55,13 +65,19 @@ SDL_KMSDRM_SYM(int,drmModeSetCursor,(int fd, uint32_t crtcId, uint32_t bo_handle
|
SDL_KMSDRM_SYM(int,drmModeSetCursor2,(int fd, uint32_t crtcId, uint32_t bo_handle,
|
uint32_t width, uint32_t height,
|
int32_t hot_x, int32_t hot_y))
|
+SDL_KMSDRM_SYM(int,drmModeSetPlane,(int fd, uint32_t plane_id, uint32_t crtc_id,
|
+ uint32_t fb_id, uint32_t flags,
|
+ int32_t crtc_x, int32_t crtc_y,
|
+ uint32_t crtc_w, uint32_t crtc_h,
|
+ uint32_t src_x, uint32_t src_y,
|
+ uint32_t src_w, uint32_t src_h))
|
SDL_KMSDRM_SYM(int,drmModeMoveCursor,(int fd, uint32_t crtcId, int x, int y))
|
SDL_KMSDRM_SYM(drmModeEncoderPtr,drmModeGetEncoder,(int fd, uint32_t encoder_id))
|
SDL_KMSDRM_SYM(drmModeConnectorPtr,drmModeGetConnector,(int fd, uint32_t connector_id))
|
SDL_KMSDRM_SYM(int,drmHandleEvent,(int fd,drmEventContextPtr evctx))
|
SDL_KMSDRM_SYM(int,drmModePageFlip,(int fd, uint32_t crtc_id, uint32_t fb_id,
|
uint32_t flags, void *user_data))
|
-
|
+SDL_KMSDRM_SYM(int,drmSetClientCap,(int fd, uint64_t capability, uint64_t value))
|
|
SDL_KMSDRM_MODULE(GBM)
|
SDL_KMSDRM_SYM(int,gbm_device_get_fd,(struct gbm_device *gbm))
|
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
|
index ee3ac05..0e75156 100644
|
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
|
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c
|
@@ -224,12 +224,19 @@ KMSDRM_WaitPageFlip(_THIS, SDL_WindowData *wdata, int timeout) {
|
SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
|
|
while (wdata->waiting_for_flip) {
|
+ int ret;
|
+
|
vdata->drm_pollfd.revents = 0;
|
- if (poll(&vdata->drm_pollfd, 1, timeout) < 0) {
|
+ ret = poll(&vdata->drm_pollfd, 1, timeout);
|
+ if (ret < 0) {
|
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll error");
|
return SDL_FALSE;
|
}
|
|
+ if (ret == 0) {
|
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "DRM poll timeout");
|
+ }
|
+
|
if (vdata->drm_pollfd.revents & (POLLHUP | POLLERR)) {
|
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "DRM poll hup or error");
|
return SDL_FALSE;
|
@@ -268,6 +275,7 @@ KMSDRM_VideoInit(_THIS)
|
drmModeRes *resources = NULL;
|
drmModeConnector *connector = NULL;
|
drmModeEncoder *encoder = NULL;
|
+ drmModePlaneRes *plane_res = NULL;
|
SDL_DisplayMode current_mode;
|
SDL_VideoDisplay display;
|
|
@@ -295,6 +303,9 @@ KMSDRM_VideoInit(_THIS)
|
}
|
SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Opened DRM FD (%d)", vdata->drm_fd);
|
|
+ KMSDRM_drmSetClientCap(vdata->drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
+ KMSDRM_drmSetClientCap(vdata->drm_fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
+
|
vdata->gbm = KMSDRM_gbm_create_device(vdata->drm_fd);
|
if (vdata->gbm == NULL) {
|
ret = SDL_SetError("Couldn't create gbm device.");
|
@@ -362,6 +373,56 @@ KMSDRM_VideoInit(_THIS)
|
data->crtc_id = encoder->crtc_id;
|
data->cur_mode = vdata->saved_crtc->mode;
|
|
+ plane_res = KMSDRM_drmModeGetPlaneResources(vdata->drm_fd);
|
+ if (!plane_res) {
|
+ ret = SDL_SetError("drmModeGetPlaneResources(%d) failed", vdata->drm_fd);
|
+ goto cleanup;
|
+ }
|
+ for (i = 0; i < plane_res->count_planes; i++) {
|
+ int j;
|
+ drmModeObjectPropertiesPtr props;
|
+ uint32_t plane_id = plane_res->planes[i];
|
+ drmModePlane *plane = KMSDRM_drmModeGetPlane(vdata->drm_fd, plane_id);
|
+ if (!plane) {
|
+ ret = SDL_SetError("drmModeGetPlane(%d)(%d) failed", vdata->drm_fd, plane_id);
|
+ goto cleanup;
|
+ }
|
+ props = KMSDRM_drmModeObjectGetProperties(vdata->drm_fd, plane_id, DRM_MODE_OBJECT_PLANE);
|
+ if (!props) {
|
+ ret = SDL_SetError("drmModeObjectGetProperties(%d)(%d) failed", vdata->drm_fd, plane_id);
|
+ KMSDRM_drmModeFreePlane(plane);
|
+ goto cleanup;
|
+ }
|
+ for (j = 0; j < props->count_props; j++) {
|
+ int z;
|
+ drmModePropertyPtr p = KMSDRM_drmModeGetProperty(vdata->drm_fd, props->props[j]);
|
+ uint64_t value = props->prop_values[j];
|
+
|
+ if (!p) {
|
+ SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "drmModeGetProperty(%d)(%d) failed\n",
|
+ vdata->drm_fd, plane_id);
|
+ continue;
|
+ }
|
+ if (strcmp(p->name, "type"))
|
+ continue;
|
+ for (z = 0; z < p->count_enums; z++) {
|
+ int n;
|
+ static const char* names[3] = { "Overlay", "Primary", "Cursor" };
|
+ if (p->enums[z].value != value)
|
+ continue;
|
+ for (n = 0; n < 3; n++) {
|
+ if (!strcmp(p->enums[z].name, names[n])) {
|
+ data->plane_ids[n] = plane_id;
|
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "%s : %d\n", names[n], plane_id);
|
+ break;
|
+ }
|
+ }
|
+ }
|
+ KMSDRM_drmModeFreeProperty(p);
|
+ }
|
+ KMSDRM_drmModeFreeObjectProperties(props);
|
+ }
|
+
|
SDL_zero(current_mode);
|
|
current_mode.w = vdata->saved_crtc->mode.hdisplay;
|
@@ -404,6 +465,8 @@ cleanup:
|
KMSDRM_drmModeFreeConnector(connector);
|
if (resources != NULL)
|
KMSDRM_drmModeFreeResources(resources);
|
+ if (plane_res != NULL)
|
+ KMSDRM_drmModeFreePlaneResources(plane_res);
|
|
if (ret != 0) {
|
/* Error (complete) cleanup */
|
@@ -482,6 +545,7 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
SDL_VideoDisplay *display;
|
SDL_VideoData *vdata = ((SDL_VideoData *)_this->driverdata);
|
Uint32 surface_fmt, surface_flags;
|
+ char *display_plane_type = NULL;
|
|
/* Allocate window internal data */
|
wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
|
@@ -526,7 +590,22 @@ KMSDRM_CreateWindow(_THIS, SDL_Window * window)
|
drmModePageFlip to work, and we can't do it until EGL is completely setup, because we
|
need to do eglSwapBuffers so we can get a valid GBM buffer object to call
|
drmModeSetCrtc on it. */
|
- wdata->crtc_ready = SDL_FALSE;
|
+ wdata->crtc_ready = SDL_FALSE;
|
+ display_plane_type = getenv("SDL2_DISPLAY_PLANE_TYPE");
|
+
|
+ if (!display_plane_type)
|
+ wdata->plane_id = 0;
|
+ else {
|
+ if (!strcmp(display_plane_type, "OVERLAY"))
|
+ wdata->plane_id = ((SDL_DisplayData *)display->driverdata)->plane_ids[0];
|
+ else if (!strcmp(display_plane_type, "PRIMARY"))
|
+ wdata->plane_id = ((SDL_DisplayData *)display->driverdata)->plane_ids[1];
|
+ else if (!strcmp(display_plane_type, "CURSOR"))
|
+ wdata->plane_id = ((SDL_DisplayData *)display->driverdata)->plane_ids[2];
|
+ else
|
+ wdata->plane_id = 0;
|
+ }
|
+ SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Window set to plane id : %d\n", wdata->plane_id);
|
|
/* Setup driver data for this window */
|
window->driverdata = wdata;
|
diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.h b/src/video/kmsdrm/SDL_kmsdrmvideo.h
|
index 71f0de7..df41115 100644
|
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.h
|
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.h
|
@@ -53,6 +53,7 @@ typedef struct SDL_DisplayData
|
uint32_t encoder_id;
|
uint32_t crtc_id;
|
drmModeModeInfo cur_mode;
|
+ uint32_t plane_ids[3]; /* Overlay, Primary, Cursor */
|
} SDL_DisplayData;
|
|
|
@@ -63,6 +64,7 @@ typedef struct SDL_WindowData
|
struct gbm_bo *next_bo;
|
SDL_bool waiting_for_flip;
|
SDL_bool crtc_ready;
|
+ uint32_t plane_id;
|
#if SDL_VIDEO_OPENGL_EGL
|
EGLSurface egl_surface;
|
#endif
|
--
|
2.7.4
|