summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_plane_helper.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2016-08-08 10:55:10 +0300
committerSean Paul <seanpaul@chromium.org>2016-08-08 14:19:45 -0400
commitdf86af9133b4958a04c44828d29617eb1a6ff31c (patch)
tree780d449387d54ad0a8bc09fc4d390d7f4fc7d56f /drivers/gpu/drm/drm_plane_helper.c
parentd7da824d9edeb7d83676c11d800b8243d87eafbf (diff)
drm/plane-helper: Add drm_plane_helper_check_state()
Add a version of drm_plane_helper_check_update() which takes a plane state instead of having the caller pass in everything. And to reduce code duplication, let's reimplement drm_plane_helper_check_update() in terms of the new function, by having a tempororary plane state on the stack. v2: Add a note that the functions modifies the state (Chris) v3: Fix drm_plane_helper_check_update() y coordinates (Daniel Kurtz) Cc: Daniel Kurtz <djkurtz@chromium.org> Cc: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Sean Paul <seanpaul@chromium.org> (v2) Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Sean Paul <seanpaul@chromium.org> Link: http://patchwork.freedesktop.org/patch/msgid/1470642910-14073-1-git-send-email-ville.syrjala@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/drm_plane_helper.c')
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c139
1 files changed, 107 insertions, 32 deletions
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index c360e30847dd..b522aabd1ab0 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -108,14 +108,9 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
}
/**
- * drm_plane_helper_check_update() - Check plane update for validity
- * @plane: plane object to update
- * @crtc: owning CRTC of owning plane
- * @fb: framebuffer to flip onto plane
- * @src: source coordinates in 16.16 fixed point
- * @dest: integer destination coordinates
+ * drm_plane_helper_check_state() - Check plane state for validity
+ * @state: plane state to check
* @clip: integer clipping coordinates
- * @rotation: plane rotation
* @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point
* @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point
* @can_position: is it legal to position the plane such that it
@@ -123,10 +118,9 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
* only be false for primary planes.
* @can_update_disabled: can the plane be updated while the crtc
* is disabled?
- * @visible: output parameter indicating whether plane is still visible after
- * clipping
*
- * Checks that a desired plane update is valid. Drivers that provide
+ * Checks that a desired plane update is valid, and updates various
+ * bits of derived state (clipped coordinates etc.). Drivers that provide
* their own plane handling rather than helper-provided implementations may
* still wish to call this function to avoid duplication of error checking
* code.
@@ -134,29 +128,38 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc,
* RETURNS:
* Zero if update appears valid, error code on failure
*/
-int drm_plane_helper_check_update(struct drm_plane *plane,
- struct drm_crtc *crtc,
- struct drm_framebuffer *fb,
- struct drm_rect *src,
- struct drm_rect *dest,
- const struct drm_rect *clip,
- unsigned int rotation,
- int min_scale,
- int max_scale,
- bool can_position,
- bool can_update_disabled,
- bool *visible)
+int drm_plane_helper_check_state(struct drm_plane_state *state,
+ const struct drm_rect *clip,
+ int min_scale,
+ int max_scale,
+ bool can_position,
+ bool can_update_disabled)
{
+ struct drm_crtc *crtc = state->crtc;
+ struct drm_framebuffer *fb = state->fb;
+ struct drm_rect *src = &state->src;
+ struct drm_rect *dst = &state->dst;
+ unsigned int rotation = state->rotation;
int hscale, vscale;
+ src->x1 = state->src_x;
+ src->y1 = state->src_y;
+ src->x2 = state->src_x + state->src_w;
+ src->y2 = state->src_y + state->src_h;
+
+ dst->x1 = state->crtc_x;
+ dst->y1 = state->crtc_y;
+ dst->x2 = state->crtc_x + state->crtc_w;
+ dst->y2 = state->crtc_y + state->crtc_h;
+
if (!fb) {
- *visible = false;
+ state->visible = false;
return 0;
}
/* crtc should only be NULL when disabling (i.e., !fb) */
if (WARN_ON(!crtc)) {
- *visible = false;
+ state->visible = false;
return 0;
}
@@ -168,20 +171,20 @@ int drm_plane_helper_check_update(struct drm_plane *plane,
drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
/* Check scaling */
- hscale = drm_rect_calc_hscale(src, dest, min_scale, max_scale);
- vscale = drm_rect_calc_vscale(src, dest, min_scale, max_scale);
+ hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
+ vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
if (hscale < 0 || vscale < 0) {
DRM_DEBUG_KMS("Invalid scaling of plane\n");
- drm_rect_debug_print("src: ", src, true);
- drm_rect_debug_print("dst: ", dest, false);
+ drm_rect_debug_print("src: ", &state->src, true);
+ drm_rect_debug_print("dst: ", &state->dst, false);
return -ERANGE;
}
- *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale);
+ state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
- if (!*visible)
+ if (!state->visible)
/*
* Plane isn't visible; some drivers can handle this
* so we just return success here. Drivers that can't
@@ -191,15 +194,87 @@ int drm_plane_helper_check_update(struct drm_plane *plane,
*/
return 0;
- if (!can_position && !drm_rect_equals(dest, clip)) {
+ if (!can_position && !drm_rect_equals(dst, clip)) {
DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
- drm_rect_debug_print("dst: ", dest, false);
+ drm_rect_debug_print("dst: ", dst, false);
drm_rect_debug_print("clip: ", clip, false);
return -EINVAL;
}
return 0;
}
+EXPORT_SYMBOL(drm_plane_helper_check_state);
+
+/**
+ * drm_plane_helper_check_update() - Check plane update for validity
+ * @plane: plane object to update
+ * @crtc: owning CRTC of owning plane
+ * @fb: framebuffer to flip onto plane
+ * @src: source coordinates in 16.16 fixed point
+ * @dest: integer destination coordinates
+ * @clip: integer clipping coordinates
+ * @rotation: plane rotation
+ * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point
+ * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point
+ * @can_position: is it legal to position the plane such that it
+ * doesn't cover the entire crtc? This will generally
+ * only be false for primary planes.
+ * @can_update_disabled: can the plane be updated while the crtc
+ * is disabled?
+ * @visible: output parameter indicating whether plane is still visible after
+ * clipping
+ *
+ * Checks that a desired plane update is valid. Drivers that provide
+ * their own plane handling rather than helper-provided implementations may
+ * still wish to call this function to avoid duplication of error checking
+ * code.
+ *
+ * RETURNS:
+ * Zero if update appears valid, error code on failure
+ */
+int drm_plane_helper_check_update(struct drm_plane *plane,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_rect *src,
+ struct drm_rect *dst,
+ const struct drm_rect *clip,
+ unsigned int rotation,
+ int min_scale,
+ int max_scale,
+ bool can_position,
+ bool can_update_disabled,
+ bool *visible)
+{
+ struct drm_plane_state state = {
+ .plane = plane,
+ .crtc = crtc,
+ .fb = fb,
+ .src_x = src->x1,
+ .src_y = src->y1,
+ .src_w = drm_rect_width(src),
+ .src_h = drm_rect_height(src),
+ .crtc_x = dst->x1,
+ .crtc_y = dst->y1,
+ .crtc_w = drm_rect_width(dst),
+ .crtc_h = drm_rect_height(dst),
+ .rotation = rotation,
+ .visible = *visible,
+ };
+ int ret;
+
+ ret = drm_plane_helper_check_state(&state, clip,
+ min_scale, max_scale,
+ can_position,
+ can_update_disabled);
+ if (ret)
+ return ret;
+
+ *src = state.src;
+ *dst = state.dst;
+ *visible = state.visible;
+
+ return 0;
+}
EXPORT_SYMBOL(drm_plane_helper_check_update);
/**