diff options
-rw-r--r-- | libdrm/xf86drmMode.c | 25 | ||||
-rw-r--r-- | libdrm/xf86drmMode.h | 15 | ||||
-rw-r--r-- | linux-core/drm_crtc.c | 40 | ||||
-rw-r--r-- | shared-core/drm.h | 3 |
4 files changed, 52 insertions, 31 deletions
diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index c0444e65..7f0252ce 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -144,14 +144,13 @@ drmModeResPtr drmModeGetResources(int fd) int i; drmModeResPtr r = 0; - res.count_crtcs = 0; - res.count_outputs = 0; - res.count_modes = 0; - res.modes = 0; + memset(&res, 0, sizeof(struct drm_mode_card_res)); if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) return 0; + if (res.count_fbs) + res.fb_id = drmMalloc(res.count_fbs*sizeof(uint32_t)); if (res.count_crtcs) res.crtc_id = drmMalloc(res.count_crtcs*sizeof(uint32_t)); if (res.count_outputs) @@ -159,8 +158,10 @@ drmModeResPtr drmModeGetResources(int fd) if (res.count_modes) res.modes = drmMalloc(res.count_modes*sizeof(*res.modes)); - if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) + if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) { + r = NULL; goto err_allocs; + } /* * return @@ -170,27 +171,23 @@ drmModeResPtr drmModeGetResources(int fd) if (!(r = drmMalloc(sizeof(*r)))) return 0; - r->frameBufferId = res.fb_id; + r->count_fbs = res.count_fbs; r->count_crtcs = res.count_crtcs; r->count_outputs = res.count_outputs; r->count_modes = res.count_modes; /* TODO we realy should test if these allocs fails. */ + r->fbs = drmAllocCpy(res.fb_id, res.count_fbs, sizeof(uint32_t)); r->crtcs = drmAllocCpy(res.crtc_id, res.count_crtcs, sizeof(uint32_t)); r->outputs = drmAllocCpy(res.output_id, res.count_outputs, sizeof(uint32_t)); r->modes = drmAllocCpy(res.modes, res.count_modes, sizeof(struct drm_mode_modeinfo)); - drmFree(res.crtc_id); - drmFree(res.output_id); - drmFree(res.modes); - - return r; - err_allocs: + drmFree(res.fb_id); drmFree(res.crtc_id); drmFree(res.output_id); drmFree(res.modes); - return 0; + return r; } int drmModeAddFB(int fd, uint32_t width, uint32_t height, @@ -214,7 +211,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, int drmModeRmFB(int fd, uint32_t bufferId) { - return ioctl(fd, DRM_IOCTL_MODE_RMFB, bufferId); + return ioctl(fd, DRM_IOCTL_MODE_RMFB, bufferId); } #if 0 diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h index 594eb487..4ca9e407 100644 --- a/libdrm/xf86drmMode.h +++ b/libdrm/xf86drmMode.h @@ -62,7 +62,8 @@ typedef struct _drmModeGammaTriple { typedef struct _drmModeRes { - uint32_t frameBufferId; + int count_fbs; + uint32_t *fbs; int count_crtcs; uint32_t *crtcs; @@ -77,10 +78,10 @@ typedef struct _drmModeRes { typedef struct _drmModeFrameBuffer { - uint32_t width; - uint32_t height; - uint32_t pitch; - uint8_t bpp; + uint32_t width; + uint32_t height; + uint32_t pitch; + uint8_t bpp; } drmModeFrameBuffer, *drmModeFrameBufferPtr; @@ -208,14 +209,14 @@ extern int drmModeForceProbe(int fd, uint32_t outputId); /** * Retrive information about framebuffer bufferId */ -extern drmModeFrameBufferPtr drmModeGetFramebuffer(int fd, +extern drmModeFrameBufferPtr drmModeGetFB(int fd, uint32_t bufferId); /** * Creates a new framebuffer with an buffer object as its scanout buffer. */ extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, - uint8_t bpp, uint32_t pitch, drmBO *bo, uint32_t *buf_id); + uint8_t bpp, uint32_t pitch, drmBO *bo, uint32_t *buf_id); /** * Destroies the given framebuffer. */ diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index 1899df2d..12705272 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -84,7 +84,6 @@ struct drm_crtc *drm_crtc_create(drm_device_t *dev, crtc->funcs = funcs; crtc->id = drm_mode_idr_get(dev, crtc); - DRM_DEBUG("crtc %p got id %d\n", crtc, crtc->id); spin_lock(&dev->mode_config.config_lock); list_add_tail(&crtc->head, &dev->mode_config.crtc_list); @@ -291,7 +290,6 @@ bool drm_set_desired_modes(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { output = NULL; - DRM_DEBUG("crtc is %d\n", crtc->id); list_for_each_entry(list_output, &dev->mode_config.output_list, head) { if (list_output->crtc == crtc) { output = list_output; @@ -610,7 +608,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, if (crtc_info->x != crtc->x || crtc_info->y != crtc->y) changed = true; - if (crtc->mode.mode_id != new_mode->mode_id) + if (new_mode && (crtc->mode.mode_id != new_mode->mode_id)) changed = true; list_for_each_entry(output, &dev->mode_config.output_list, head) { @@ -633,8 +631,8 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, } if (changed) { - crtc->enabled = new_mode != NULL; - if (new_mode) { + crtc->enabled = (new_mode != NULL); + if (new_mode != NULL) { DRM_DEBUG("attempting to set mode from userspace\n"); drm_mode_debug_printmodeline(dev, new_mode); if (!drm_crtc_set_mode(crtc, new_mode, crtc_info->x, @@ -648,7 +646,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, } crtc->desired_x = crtc_info->x; crtc->desired_y = crtc_info->y; - crtc->desired_mode = new_mode; + crtc->desired_mode = new_mode; } drm_disable_unused_functions(dev); } @@ -687,6 +685,7 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, struct drm_mode_card_res __user *argp = (void __user *)arg; struct drm_mode_card_res card_res; struct list_head *lh; + struct drm_framebuffer *fb; struct drm_output *output; struct drm_crtc *crtc; struct drm_mode_modeinfo u_mode; @@ -695,10 +694,14 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, int mode_count= 0; int output_count = 0; int crtc_count = 0; + int fb_count = 0; int copied = 0; memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo)); + list_for_each(lh, &dev->mode_config.fb_list) + fb_count++; + list_for_each(lh, &dev->mode_config.crtc_list) crtc_count++; @@ -722,7 +725,19 @@ int drm_mode_getresources(struct inode *inode, struct file *filp, } } - /* handle this in 3 parts */ + /* handle this in 4 parts */ + /* FBs */ + if (card_res.count_fbs >= fb_count) { + copied = 0; + list_for_each_entry(fb, &dev->mode_config.fb_list, head) { + if (put_user(fb->id, &card_res.fb_id[copied++])) { + retcode = -EFAULT; + goto done; + } + } + } + card_res.count_fbs = fb_count; + /* CRTCs */ if (card_res.count_crtcs >= crtc_count) { copied = 0; @@ -840,11 +855,9 @@ int drm_mode_getoutput(struct inode *inode, struct file *filp, if (!output || (output->id != out_resp.output)) return -EINVAL; - DRM_DEBUG("about to count modes: %s\n", output->name); list_for_each_entry(mode, &output->modes, head) mode_count++; - DRM_DEBUG("about to count modes %d %d %p\n", mode_count, out_resp.count_modes, output->crtc); strncpy(out_resp.name, output->name, DRM_OUTPUT_NAME_LEN); out_resp.name[DRM_OUTPUT_NAME_LEN-1] = 0; @@ -1029,9 +1042,18 @@ int drm_mode_rmfb(struct inode *inode, struct file *filp, /* TODO check if we own the buffer */ /* TODO release all crtc connected to the framebuffer */ + /* bind the fb to the crtc for now */ + { + struct drm_crtc *crtc; + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + if (crtc->fb == fb) + crtc->fb = NULL; + } + } /* TODO unhock the destructor from the buffer object */ drm_framebuffer_destroy(fb); return 0; } + diff --git a/shared-core/drm.h b/shared-core/drm.h index f1afc049..a5330b28 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -909,7 +909,8 @@ struct drm_mode_modeinfo { struct drm_mode_card_res { - unsigned int fb_id; + int count_fbs; + unsigned int __user *fb_id; int count_crtcs; unsigned int __user *crtc_id; |