From: Ville Syrj?l? <ville.syrjala at linux.intel.com> Reduce the size of the the src/dst viewport to keep the scalign ratios in check. Also treat sprites below the minimum size as invisble. Signed-off-by: Ville Syrj?l? <ville.syrjala at linux.intel.com> --- drivers/gpu/drm/i915/intel_sprite.c | 60 ++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 93a6657..c3a5688 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -679,26 +679,19 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, return -EINVAL; } + /* + * FIXME the following code does a bunch of fuzzy adjustments to the + * coordinates and sizes. We probably need some way to decide whether + * more strict checking should be done instead. + */ max_scale = intel_plane->max_downscale << 16; min_scale = intel_plane->can_scale ? 1 : (1 << 16); - hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); - if (hscale < 0) { - DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); - drm_rect_debug_print(&src, true); - drm_rect_debug_print(&dst, false); + hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale); + BUG_ON(hscale < 0); - return hscale; - } - - vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); - if (vscale < 0) { - DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); - drm_rect_debug_print(&src, true); - drm_rect_debug_print(&dst, false); - - return vscale; - } + vscale = drm_rect_calc_vscale_relaxed(&src, &dst, min_scale, max_scale); + BUG_ON(vscale < 0); visible = drm_rect_clip_scaled(&src, &dst, &clip, hscale, vscale); @@ -708,6 +701,25 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, crtc_h = drm_rect_height(&dst); if (visible) { + /* check again in case clipping clamped the results */ + hscale = drm_rect_calc_hscale(&src, &dst, min_scale, max_scale); + if (hscale < 0) { + DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n"); + drm_rect_debug_print(&src, true); + drm_rect_debug_print(&dst, false); + + return hscale; + } + + vscale = drm_rect_calc_vscale(&src, &dst, min_scale, max_scale); + if (vscale < 0) { + DRM_DEBUG_KMS("Vertical scaling factor out of limits\n"); + drm_rect_debug_print(&src, true); + drm_rect_debug_print(&dst, false); + + return vscale; + } + /* Make the source viewport size an exact multiple of the scaling factors. */ drm_rect_adjust_size(&src, drm_rect_width(&dst) * hscale - drm_rect_width(&src), @@ -718,10 +730,6 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, * Adjust to (macro)pixel boundary, but be careful not to * increase the source viewport size, because that could * push the downscaling factor out of bounds. - * - * FIXME Should we be really strict and reject the - * config if it results in non (macro)pixel aligned - * coords? */ src_x = src.x1 >> 16; src_w = drm_rect_width(&src) >> 16; @@ -752,15 +760,11 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, /* FIXME interlacing min height is 6 */ - if (crtc_w < 3 || crtc_h < 3) { - DRM_DEBUG_KMS("Destination dimensions too small\n"); - return -EINVAL; - } + if (crtc_w < 3 || crtc_h < 3) + visible = false; - if (src_w < 3 || src_h < 3) { - DRM_DEBUG_KMS("Source dimensions too small\n"); - return -EINVAL; - } + if (src_w < 3 || src_h < 3) + visible = false; width_bytes = ((src_x * pixel_size) & 63) + src_w * pixel_size; -- 1.8.1.5