diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 4840582..7fbc0f3 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -989,25 +989,24 @@ static int check_overlay_src(struct drm_device *dev, struct drm_intel_overlay_put_image *rec, struct drm_gem_object *new_bo) { - u32 stride_mask; - int depth; int uv_hscale = uv_hsubsampling(rec->flags); int uv_vscale = uv_vsubsampling(rec->flags); - size_t tmp; + u32 stride_mask, depth, tmp; /* check src dimensions */ if (IS_845G(dev) || IS_I830(dev)) { if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY || - rec->src_width > IMAGE_MAX_WIDTH_LEGACY) + rec->src_width > IMAGE_MAX_WIDTH_LEGACY) return -EINVAL; } else { if (rec->src_height > IMAGE_MAX_HEIGHT || - rec->src_width > IMAGE_MAX_WIDTH) + rec->src_width > IMAGE_MAX_WIDTH) return -EINVAL; } + /* better safe than sorry, use 4 as the maximal subsampling ratio */ if (rec->src_height < N_VERT_Y_TAPS*4 || - rec->src_width < N_HORIZ_Y_TAPS*4) + rec->src_width < N_HORIZ_Y_TAPS*4) return -EINVAL; /* check alignment constraints */ @@ -1015,12 +1014,15 @@ static int check_overlay_src(struct drm_device *dev, case I915_OVERLAY_RGB: /* not implemented */ return -EINVAL; + case I915_OVERLAY_YUV_PACKED: - depth = packed_depth_bytes(rec->flags); if (uv_vscale != 1) return -EINVAL; + + depth = packed_depth_bytes(rec->flags); if (depth < 0) return depth; + /* ignore UV planes */ rec->stride_UV = 0; rec->offset_U = 0; @@ -1029,11 +1031,13 @@ static int check_overlay_src(struct drm_device *dev, if (rec->offset_Y % depth) return -EINVAL; break; + case I915_OVERLAY_YUV_PLANAR: if (uv_vscale < 0 || uv_hscale < 0) return -EINVAL; /* no offset restrictions for planar formats */ break; + default: return -EINVAL; } @@ -1053,8 +1057,8 @@ static int check_overlay_src(struct drm_device *dev, return -EINVAL; tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? - 4 : 8; - if (rec->stride_Y > tmp*1024 || rec->stride_UV > 2*1024) + 4096 : 8192; + if (rec->stride_Y > tmp || rec->stride_UV > 2*1024) return -EINVAL; /* check buffer dimensions */ @@ -1076,11 +1080,11 @@ static int check_overlay_src(struct drm_device *dev, if (rec->src_width/uv_hscale > rec->stride_UV) return -EINVAL; - tmp = rec->stride_Y*rec->src_height; + tmp = rec->stride_Y * rec->src_height; if (rec->offset_Y + tmp > new_bo->size) return -EINVAL; - tmp = rec->stride_UV*rec->src_height; - tmp /= uv_vscale; + + tmp = rec->stride_UV * (rec->src_height / uv_vscale); if (rec->offset_U + tmp > new_bo->size || rec->offset_V + tmp > new_bo->size) return -EINVAL; |