mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-21 11:00:11 +01:00
drm_mode: initial replacefb implemenation
This commit is contained in:
parent
df46e0691b
commit
ed072ed075
6 changed files with 85 additions and 3 deletions
|
|
@ -608,3 +608,24 @@ int drmCheckModesettingSupported(const char *busid)
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int drmModeReplaceFB(int fd, uint32_t buffer_id,
|
||||||
|
uint32_t width, uint32_t height, uint8_t depth,
|
||||||
|
uint8_t bpp, uint32_t pitch, uint32_t bo_handle)
|
||||||
|
{
|
||||||
|
struct drm_mode_fb_cmd f;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
f.width = width;
|
||||||
|
f.height = height;
|
||||||
|
f.pitch = pitch;
|
||||||
|
f.bpp = bpp;
|
||||||
|
f.depth = depth;
|
||||||
|
f.handle = bo_handle;
|
||||||
|
f.buffer_id = buffer_id;
|
||||||
|
|
||||||
|
if ((ret = ioctl(fd, DRM_IOCTL_MODE_REPLACEFB, &f)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,12 @@ extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
||||||
*/
|
*/
|
||||||
extern int drmModeRmFB(int fd, uint32_t bufferId);
|
extern int drmModeRmFB(int fd, uint32_t bufferId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace a framebuffer object with a new one - for resizing the screen.
|
||||||
|
*/
|
||||||
|
extern int drmModeReplaceFB(int fd, uint32_t buffer_id,
|
||||||
|
uint32_t width, uint32_t height, uint8_t depth,
|
||||||
|
uint8_t bpp, uint32_t pitch, uint32_t bo_handle);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Crtc functions
|
* Crtc functions
|
||||||
|
|
|
||||||
|
|
@ -1879,8 +1879,8 @@ out:
|
||||||
int drm_mode_rmfb(struct drm_device *dev,
|
int drm_mode_rmfb(struct drm_device *dev,
|
||||||
void *data, struct drm_file *file_priv)
|
void *data, struct drm_file *file_priv)
|
||||||
{
|
{
|
||||||
struct drm_framebuffer *fb = 0;
|
struct drm_framebuffer *fb = NULL;
|
||||||
struct drm_framebuffer *fbl = 0;
|
struct drm_framebuffer *fbl = NULL;
|
||||||
uint32_t *id = data;
|
uint32_t *id = data;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
@ -2513,3 +2513,54 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int drm_mode_replacefb(struct drm_device *dev,
|
||||||
|
void *data, struct drm_file *file_priv)
|
||||||
|
{
|
||||||
|
struct drm_mode_fb_cmd *r = data;
|
||||||
|
struct drm_framebuffer *fb;
|
||||||
|
struct drm_crtc *crtc;
|
||||||
|
struct drm_buffer_object *bo;
|
||||||
|
int found = 0;
|
||||||
|
struct drm_framebuffer *fbl = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
/* right replace the current bo attached to this fb with a new bo */
|
||||||
|
mutex_lock(&dev->mode_config.mutex);
|
||||||
|
ret = drm_get_buffer_object(dev, &bo, r->handle);
|
||||||
|
if (ret || !bo) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
fb = idr_find(&dev->mode_config.crtc_idr, r->buffer_id);
|
||||||
|
if (!fb || (r->buffer_id != fb->id)) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry(fbl, &file_priv->fbs, filp_head)
|
||||||
|
if (fb == fbl)
|
||||||
|
found = 1;
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
DRM_ERROR("tried to replace an fb we didn't own\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fb->bo->type == drm_bo_type_kernel)
|
||||||
|
DRM_ERROR("the bo should not be a kernel bo\n");
|
||||||
|
|
||||||
|
fb->bo = bo;
|
||||||
|
|
||||||
|
/* find all crtcs connected to this fb */
|
||||||
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||||
|
if (crtc->fb->id == r->buffer_id) {
|
||||||
|
crtc->funcs->mode_set_base(crtc, crtc->x, crtc->y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
mutex_unlock(&dev->mode_config.mutex);
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -649,6 +649,7 @@ extern int drm_mode_output_property_set_ioctl(struct drm_device *dev,
|
||||||
void *data, struct drm_file *file_priv);
|
void *data, struct drm_file *file_priv);
|
||||||
extern int drm_mode_hotplug_ioctl(struct drm_device *dev,
|
extern int drm_mode_hotplug_ioctl(struct drm_device *dev,
|
||||||
void *data, struct drm_file *file_priv);
|
void *data, struct drm_file *file_priv);
|
||||||
|
extern int drm_mode_replacefb(struct drm_device *dev,
|
||||||
|
void *data, struct drm_file *file_priv);
|
||||||
#endif /* __DRM_CRTC_H__ */
|
#endif /* __DRM_CRTC_H__ */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MODE_HOTPLUG, drm_mode_hotplug_ioctl, DRM_CONTROL_ALLOW),
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_HOTPLUG, drm_mode_hotplug_ioctl, DRM_CONTROL_ALLOW),
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_WAIT_HOTPLUG, drm_wait_hotplug, 0),
|
DRM_IOCTL_DEF(DRM_IOCTL_WAIT_HOTPLUG, drm_wait_hotplug, 0),
|
||||||
|
|
||||||
|
DRM_IOCTL_DEF(DRM_IOCTL_MODE_REPLACEFB, drm_mode_replacefb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
|
||||||
|
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
|
DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
|
||||||
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
|
||||||
DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl,
|
DRM_IOCTL_DEF(DRM_IOCTL_MM_TAKEDOWN, drm_mm_takedown_ioctl,
|
||||||
|
|
|
||||||
|
|
@ -1276,6 +1276,7 @@ struct drm_mode_hotplug {
|
||||||
#define DRM_IOCTL_MODE_HOTPLUG DRM_IOWR(0xAD, struct drm_mode_hotplug)
|
#define DRM_IOCTL_MODE_HOTPLUG DRM_IOWR(0xAD, struct drm_mode_hotplug)
|
||||||
#define DRM_IOCTL_WAIT_HOTPLUG DRM_IOWR(0xAE, union drm_wait_hotplug)
|
#define DRM_IOCTL_WAIT_HOTPLUG DRM_IOWR(0xAE, union drm_wait_hotplug)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xAF, struct drm_mode_fb_cmd)
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue