mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-25 19:13:46 +08:00
use plane for hardware cursor (not finished)
This commit is contained in:
+235
-32
@@ -769,6 +769,12 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static DrmSurfaceBuffer *drm_create_dumb_buffer(DrmVideoData* vdata,
|
||||
uint32_t drm_format, uint32_t hdr_size,
|
||||
int width, int height, int *pitch);
|
||||
|
||||
static void drm_destroy_dumb_buffer(DrmVideoData* vdata,
|
||||
DrmSurfaceBuffer *surface_buffer);
|
||||
/*
|
||||
* The following helpers derived from DRM HOWTO by David Herrmann.
|
||||
*
|
||||
@@ -827,6 +833,18 @@ static void drm_cleanup(DrmVideoData* vdata)
|
||||
GAL_FreeSurface (vdata->real_screen);
|
||||
}
|
||||
|
||||
#ifdef _MGSCHEMA_COMPOSITING
|
||||
if (vdata->cursor_buff_id) {
|
||||
drmModeRmFB(vdata->dev_fd, vdata->cursor_buff_id);
|
||||
vdata->cursor_buff_id = 0;
|
||||
}
|
||||
|
||||
if (vdata->cursor_buff) {
|
||||
drm_destroy_dumb_buffer (vdata, vdata->cursor_buff);
|
||||
vdata->cursor_buff = NULL;
|
||||
}
|
||||
#endif /* _MGSCHEMA_COMPOSITING */
|
||||
|
||||
if (vdata->scanout_buff_id) {
|
||||
/* remove frame buffer */
|
||||
drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id);
|
||||
@@ -1019,6 +1037,9 @@ static int open_drm_device(GAL_VideoDevice *device)
|
||||
else {
|
||||
device->hidden->cap_cursor_height = cursor_height;
|
||||
}
|
||||
|
||||
_WRN_PRINTF ("DRM cursor cap: w(%d), h(%d)\n",
|
||||
(int)cursor_width, (int)cursor_height);
|
||||
}
|
||||
|
||||
if (device->hidden->driver == NULL) {
|
||||
@@ -1203,16 +1224,14 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex)
|
||||
if (device->hidden->cap_dumb &&
|
||||
device->hidden->cap_cursor_width >= CURSORWIDTH &&
|
||||
device->hidden->cap_cursor_height >= CURSORHEIGHT) {
|
||||
device->info.hw_cursor = 1;
|
||||
device->SetCursor = DRM_SetCursor;
|
||||
device->MoveCursor = DRM_MoveCursor;
|
||||
}
|
||||
else {
|
||||
device->info.hw_cursor = 1;
|
||||
device->SetCursor = DRM_SetCursor_SW;
|
||||
device->MoveCursor = DRM_MoveCursor_SW;
|
||||
}
|
||||
#endif
|
||||
#endif /* IS_COMPOSITING_SCHEMA */
|
||||
|
||||
/* set accelerated methods in DRM_VideoInit */
|
||||
device->CheckHWBlit = NULL;
|
||||
@@ -1465,6 +1484,11 @@ static int DRM_VideoInit(_THIS, GAL_PixelFormat *vformat)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* we must initialize the video information after created the device */
|
||||
if (this->SetCursor) {
|
||||
this->info.hw_cursor = 1;
|
||||
}
|
||||
|
||||
if (this->hidden->driver) {
|
||||
if (this->hidden->driver_ops->clear_buffer) {
|
||||
this->info.blit_fill = 1;
|
||||
@@ -1709,6 +1733,163 @@ static int drm_setup_scanout_buffer (DrmVideoData* vdata,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if IS_COMPOSITING_SCHEMA
|
||||
/* check to see whether the plane is ok for cursor */
|
||||
static uint32_t check_plane_suitable_for_cursor(DrmVideoData* vdata,
|
||||
drmModePlanePtr plane, uint32_t fourcc)
|
||||
{
|
||||
int i, j, k;
|
||||
uint32_t plane_id = 0;
|
||||
|
||||
for (i = 0; i < plane->count_formats; i++) {
|
||||
_WRN_PRINTF ("plane format (%d): %c%c%c%c\n", i,
|
||||
plane->formats[i], plane->formats[i] >> 8,
|
||||
plane->formats[i] >> 16, plane->formats[i] >> 24);
|
||||
if (plane->formats[i] != fourcc)
|
||||
continue;
|
||||
|
||||
drmModeObjectPropertiesPtr props =
|
||||
drmModeObjectGetProperties(vdata->dev_fd, plane->plane_id,
|
||||
DRM_MODE_OBJECT_PLANE);
|
||||
if (!props)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < props->count_props; j++) {
|
||||
drmModePropertyPtr prop =
|
||||
drmModeGetProperty (vdata->dev_fd, props->props[j]);
|
||||
|
||||
_WRN_PRINTF ("prop name: %s\n", prop->name);
|
||||
if (strcmp(prop->name, "type") == 0 &&
|
||||
drm_property_type_is(prop, DRM_MODE_PROP_ENUM)) {
|
||||
for (k = 0; k < prop->count_enums; k++) {
|
||||
_WRN_PRINTF ("prop enum value (%d): %d\n",
|
||||
k, (int)prop->enums[k].value);
|
||||
if (prop->enums[k].value == DRM_PLANE_TYPE_CURSOR) {
|
||||
plane_id = plane->plane_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drmModeFreeProperty(prop);
|
||||
if (plane_id)
|
||||
break;
|
||||
}
|
||||
|
||||
drmModeFreeObjectProperties (props);
|
||||
if (plane_id)
|
||||
break;
|
||||
}
|
||||
|
||||
return plane_id;
|
||||
}
|
||||
|
||||
static int drm_setup_cursor_plane (DrmVideoData* vdata, uint32_t drm_format,
|
||||
uint32_t width, uint32_t height)
|
||||
{
|
||||
uint32_t plane_id = 0;
|
||||
int pitch;
|
||||
uint32_t handles[4], pitches[4], offsets[4];
|
||||
uint32_t plane_flags = 0;
|
||||
int i, ret = -1;
|
||||
drmModePlaneResPtr plane_res = NULL;
|
||||
|
||||
#if 0
|
||||
int pipe = -1;
|
||||
drmModeRes *res;
|
||||
|
||||
res = drmModeGetResources(vdata->dev_fd);
|
||||
if (!res) return ret;
|
||||
for (i = 0; i < res->count_crtcs; i++) {
|
||||
if (vdata->saved_info->crtc == res->crtcs[i]) {
|
||||
pipe = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
drmModeFreeResources(res);
|
||||
assert (pipe >= 0);
|
||||
#endif
|
||||
|
||||
plane_res = drmModeGetPlaneResources (vdata->dev_fd);
|
||||
if (!plane_res) {
|
||||
_WRN_PRINTF( "drmModeGetPlaneResources failed: %m\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < plane_res->count_planes; i ++) {
|
||||
drmModePlanePtr plane =
|
||||
drmModeGetPlane(vdata->dev_fd, plane_res->planes[i]);
|
||||
if (plane == NULL) {
|
||||
_WRN_PRINTF( "drmModeGetPlane failed: %m\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((plane->crtc_id == 0 ||
|
||||
plane->crtc_id == vdata->saved_info->crtc)) {
|
||||
plane_id = check_plane_suitable_for_cursor(vdata, plane,
|
||||
drm_format);
|
||||
}
|
||||
else {
|
||||
_WRN_PRINTF( "possible_crtcs: %x, crtc_id: %u\n",
|
||||
plane->possible_crtcs, plane->crtc_id);
|
||||
}
|
||||
|
||||
drmModeFreePlane(plane);
|
||||
if (plane_id)
|
||||
break;
|
||||
}
|
||||
|
||||
drmModeFreePlaneResources (plane_res);
|
||||
|
||||
if (plane_id == 0) {
|
||||
_WRN_PRINTF( "no available plane for cursor in format %c%c%c%c\n",
|
||||
drm_format, drm_format >> 8, drm_format >> 16, drm_format >> 24);
|
||||
goto error;
|
||||
}
|
||||
|
||||
vdata->cursor_buff = drm_create_dumb_buffer (vdata, drm_format, 0,
|
||||
width, height, &pitch);
|
||||
if (vdata->cursor_buff == NULL)
|
||||
return ret;
|
||||
|
||||
handles[0] = vdata->cursor_buff->handle;
|
||||
pitches[0] = pitch;
|
||||
offsets[0] = 0;
|
||||
|
||||
ret = drmModeAddFB2(vdata->dev_fd, width, height, drm_format,
|
||||
handles, pitches, offsets, &vdata->cursor_buff_id, plane_flags);
|
||||
if (ret) {
|
||||
_WRN_PRINTF ("drmModeAddFB2 failed: %m\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* note src coords (last 4 args) are in Q16 format */
|
||||
if (drmModeSetPlane(vdata->dev_fd, plane_id,
|
||||
vdata->saved_info->crtc, vdata->cursor_buff_id,
|
||||
plane_flags, 0, 0, width, height,
|
||||
0, 0, width << 16, height << 16)) {
|
||||
_WRN_PRINTF ("failed to enable cursor plane: %m\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
vdata->cursor_plane_id = plane_id;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (vdata->cursor_buff_id) {
|
||||
drmModeRmFB(vdata->dev_fd, vdata->cursor_buff_id);
|
||||
vdata->cursor_buff_id = 0;
|
||||
}
|
||||
|
||||
if (vdata->cursor_buff) {
|
||||
drm_destroy_dumb_buffer (vdata, vdata->cursor_buff);
|
||||
vdata->cursor_buff = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* IS_COMPOSITING_SCHEMA */
|
||||
|
||||
static inline uint32_t nr_lines_for_header (uint32_t header_size,
|
||||
uint32_t width, uint32_t height, int cpp)
|
||||
{
|
||||
@@ -1772,9 +1953,9 @@ static DrmSurfaceBuffer *drm_create_dumb_buffer(DrmVideoData* vdata,
|
||||
surface_buffer->size = creq.size;
|
||||
*pitch = creq.pitch;
|
||||
|
||||
_DBG_PRINTF ("Surface buffer info: w(%u), h(%u), "
|
||||
"pitch(%u), size (%lu), offset (%lu)\n",
|
||||
width, height, creq.pitch,
|
||||
_DBG_PRINTF ("Surface buffer info: handle(%u), w(%u), h(%u), "
|
||||
"pitch(%u), size(%lu), offset(%lu)\n",
|
||||
creq.handle, width, height, creq.pitch,
|
||||
surface_buffer->size, surface_buffer->offset);
|
||||
|
||||
/* prepare buffer for memory mapping */
|
||||
@@ -1898,12 +2079,12 @@ static DrmSurfaceBuffer *drm_create_dumb_buffer_from_prime_fd(DrmVideoData* vdat
|
||||
_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",
|
||||
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;
|
||||
@@ -2075,6 +2256,15 @@ static GAL_Surface *DRM_SetVideoMode(_THIS, GAL_Surface *current,
|
||||
GAL_SetAlpha (vdata->shadow_screen, 0, 0);
|
||||
}
|
||||
|
||||
#if IS_COMPOSITING_SCHEMA
|
||||
if (this->info.hw_cursor && drm_setup_cursor_plane (vdata,
|
||||
DRM_FORMAT_XRGB8888, CURSORWIDTH, CURSORHEIGHT)) {
|
||||
_WRN_PRINTF("cannot setup cursor plane\n");
|
||||
this->SetCursor = DRM_SetCursor_SW;
|
||||
this->MoveCursor = DRM_MoveCursor_SW;
|
||||
}
|
||||
#endif /* IS_COMPOSITING_SCHEMA */
|
||||
|
||||
GAL_FreeSurface (current);
|
||||
if (vdata->shadow_screen)
|
||||
return vdata->shadow_screen;
|
||||
@@ -2319,11 +2509,28 @@ static int DRM_SetCursor(_THIS, GAL_Surface *surface, int hot_x, int hot_y)
|
||||
DrmSurfaceBuffer* surface_buffer;
|
||||
|
||||
surface_buffer = (DrmSurfaceBuffer*)surface->hwdata;
|
||||
if (surface_buffer) {
|
||||
retval = drmModeSetCursor2 (vdata->dev_fd, vdata->saved_crtc->crtc_id,
|
||||
surface_buffer->handle, surface->w, surface->h, hot_x, hot_y);
|
||||
if (retval)
|
||||
_WRN_PRINTF ("failed to call drmModeSetCursor2: %m\n");
|
||||
assert (surface_buffer && vdata->cursor_buff);
|
||||
|
||||
#if 0
|
||||
retval = drmModeSetCursor2 (vdata->dev_fd, vdata->saved_info->crtc,
|
||||
surface_buffer->handle, surface->w, surface->h, hot_x, hot_y);
|
||||
if (retval)
|
||||
_WRN_PRINTF ("failed to call drmModeSetCursor2(%u,%u,%d,%d,%d,%d):%m\n",
|
||||
vdata->saved_info->crtc, surface_buffer->handle,
|
||||
surface->w, surface->h, hot_x, hot_y);
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
uint8_t *src, *dst;
|
||||
|
||||
src = surface_buffer->buff + surface_buffer->offset;
|
||||
dst = vdata->cursor_buff->buff + vdata->cursor_buff->offset;
|
||||
for (i = 0; i < surface->h; i++) {
|
||||
memcpy (dst, src, surface->pitch);
|
||||
dst += surface->pitch;
|
||||
src += surface->pitch;
|
||||
}
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -2334,10 +2541,17 @@ static int DRM_MoveCursor(_THIS, int x, int y)
|
||||
int retval = -1;
|
||||
DrmVideoData* vdata = this->hidden;
|
||||
|
||||
retval = drmModeMoveCursor (vdata->dev_fd, vdata->saved_crtc->crtc_id, x, y);
|
||||
#if 0
|
||||
retval = drmModeMoveCursor (vdata->dev_fd, vdata->cursor_plane_id, x, y);
|
||||
if (retval) {
|
||||
_WRN_PRINTF ("failed to call drmModeMoveCursor: %m\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
retval = drmModeSetPlane(vdata->dev_fd, vdata->cursor_plane_id,
|
||||
vdata->saved_info->crtc, vdata->cursor_buff_id,
|
||||
0, x, y, CURSORWIDTH, CURSORHEIGHT,
|
||||
0, 0, CURSORWIDTH << 16, CURSORHEIGHT << 16);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@@ -2868,10 +3082,6 @@ static void DRM_UpdateRects (_THIS, int numrects, GAL_Rect *rects)
|
||||
hdr = (GAL_ShadowSurfaceHeader*)
|
||||
((DrmSurfaceBuffer*)this->hidden->shadow_screen->hwdata)->buff;
|
||||
|
||||
#if IS_SHAREDFB_SCHEMA_PROCS
|
||||
//sem_wait(&hdr->sem_lock);
|
||||
#endif
|
||||
|
||||
bound = hdr->dirty_rc;
|
||||
for (i = 0; i < numrects; i++) {
|
||||
RECT rc;
|
||||
@@ -2885,10 +3095,8 @@ static void DRM_UpdateRects (_THIS, int numrects, GAL_Rect *rects)
|
||||
}
|
||||
|
||||
hdr->dirty_rc = bound;
|
||||
|
||||
#if IS_SHAREDFB_SCHEMA_PROCS
|
||||
//sem_post(&hdr->sem_lock);
|
||||
#endif
|
||||
bound = GetScreenRect();
|
||||
IntersectRect (&hdr->dirty_rc, &hdr->dirty_rc, &bound);
|
||||
}
|
||||
|
||||
static BOOL DRM_SyncUpdate (_THIS)
|
||||
@@ -2902,10 +3110,6 @@ static BOOL DRM_SyncUpdate (_THIS)
|
||||
hdr = (GAL_ShadowSurfaceHeader*)
|
||||
((DrmSurfaceBuffer*)this->hidden->shadow_screen->hwdata)->buff;
|
||||
|
||||
#if IS_SHAREDFB_SCHEMA_PROCS
|
||||
//sem_wait(&hdr->sem_lock);
|
||||
#endif
|
||||
|
||||
if (IsRectEmpty (&hdr->dirty_rc))
|
||||
goto ret;
|
||||
|
||||
@@ -2919,6 +3123,9 @@ static BOOL DRM_SyncUpdate (_THIS)
|
||||
src_rect.h = RECTH (bound);
|
||||
dst_rect = src_rect;
|
||||
|
||||
_WRN_PRINTF ("calling GAL_BlitSurface: %d, %d, %d, %d\n",
|
||||
src_rect.x, src_rect.y, src_rect.w, src_rect.h);
|
||||
|
||||
GAL_BlitSurface (this->hidden->shadow_screen, &src_rect,
|
||||
this->hidden->real_screen, &dst_rect);
|
||||
#ifdef _MGSCHEMA_COMPOSITING
|
||||
@@ -2947,11 +3154,7 @@ static BOOL DRM_SyncUpdate (_THIS)
|
||||
}
|
||||
|
||||
SetRectEmpty (&hdr->dirty_rc);
|
||||
|
||||
ret:
|
||||
#if IS_SHAREDFB_SCHEMA_PROCS
|
||||
//sem_post(&hdr->sem_lock);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user