allow framebuffer changes on the crtc setup

main
Dave Airlie 2007-04-12 08:54:31 +10:00
parent a81558d8b3
commit 981f8156de
3 changed files with 20 additions and 6 deletions

View File

@ -276,7 +276,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
r->mode = crtc.mode;
// r->width = crtc.width;
// r->height = crtc.height;
r->bufferId = crtc.fb_id;
r->buffer_id = crtc.fb_id;
r->gamma_size = crtc.gamma_size;
r->count_outputs = crtc.count_outputs;
r->count_possibles = crtc.count_possibles;

View File

@ -80,7 +80,7 @@ typedef struct drm_mode_fb_cmd drmModeFrameBuffer, *drmModeFrameBufferPtr;
typedef struct _drmModeCrtc {
unsigned int bufferId; /**< Buffer currently connected to */
unsigned int buffer_id; /**< FB id to connect to 0 = disconnect*/
uint32_t x, y; /**< Position on the frameuffer */
uint32_t width, height;

View File

@ -590,7 +590,7 @@ void drm_mode_config_cleanup(drm_device_t *dev)
}
EXPORT_SYMBOL(drm_mode_config_cleanup);
int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_display_mode *new_mode, struct drm_output **output_set)
int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_display_mode *new_mode, struct drm_output **output_set, struct drm_framebuffer *fb)
{
drm_device_t *dev = crtc->dev;
struct drm_crtc **save_crtcs, *new_crtc;
@ -603,6 +603,9 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
if (!save_crtcs)
return -ENOMEM;
if (crtc->fb != fb)
changed = true;
if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
changed = true;
@ -629,6 +632,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
}
if (changed) {
crtc->fb = fb;
crtc->enabled = (new_mode != NULL);
if (new_mode != NULL) {
DRM_DEBUG("attempting to set mode from userspace\n");
@ -897,6 +901,7 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
struct drm_crtc *crtc;
struct drm_output **output_set = NULL, *output;
struct drm_display_mode *mode;
struct drm_framebuffer *fb = NULL;
int retcode = 0;
int i;
@ -911,6 +916,15 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
}
if (crtc_req.mode) {
/* if we have a mode we need a framebuffer */
if (crtc_req.fb_id) {
fb = idr_find(&dev->mode_config.crtc_idr, crtc_req.fb_id);
if (!fb || (fb->id != crtc_req.fb_id)) {
DRM_DEBUG("Unknown FB ID%d\n", crtc_req.fb_id);
return -EINVAL;
}
}
mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode);
if (!mode || (mode->mode_id != crtc_req.mode))
{
@ -935,8 +949,8 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
return -EINVAL;
}
if (crtc_req.count_outputs > 0 && !mode) {
DRM_DEBUG("Count outputs is %d but no mode set\n", crtc_req.count_outputs);
if (crtc_req.count_outputs > 0 && !mode && !fb) {
DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req.count_outputs);
return -EINVAL;
}
@ -960,7 +974,7 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,
}
}
retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set);
retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb);
return retcode;
}