diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2016-08-08 03:55:10 -0400 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2016-08-08 14:19:45 -0400 |
commit | df86af9133b4958a04c44828d29617eb1a6ff31c (patch) | |
tree | 780d449387d54ad0a8bc09fc4d390d7f4fc7d56f | |
parent | d7da824d9edeb7d83676c11d800b8243d87eafbf (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
-rw-r--r-- | drivers/gpu/drm/drm_plane_helper.c | 139 | ||||
-rw-r--r-- | include/drm/drm_plane_helper.h | 5 |
2 files changed, 112 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, | |||
108 | } | 108 | } |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * drm_plane_helper_check_update() - Check plane update for validity | 111 | * drm_plane_helper_check_state() - Check plane state for validity |
112 | * @plane: plane object to update | 112 | * @state: plane state to check |
113 | * @crtc: owning CRTC of owning plane | ||
114 | * @fb: framebuffer to flip onto plane | ||
115 | * @src: source coordinates in 16.16 fixed point | ||
116 | * @dest: integer destination coordinates | ||
117 | * @clip: integer clipping coordinates | 113 | * @clip: integer clipping coordinates |
118 | * @rotation: plane rotation | ||
119 | * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point | 114 | * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point |
120 | * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point | 115 | * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point |
121 | * @can_position: is it legal to position the plane such that it | 116 | * @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, | |||
123 | * only be false for primary planes. | 118 | * only be false for primary planes. |
124 | * @can_update_disabled: can the plane be updated while the crtc | 119 | * @can_update_disabled: can the plane be updated while the crtc |
125 | * is disabled? | 120 | * is disabled? |
126 | * @visible: output parameter indicating whether plane is still visible after | ||
127 | * clipping | ||
128 | * | 121 | * |
129 | * Checks that a desired plane update is valid. Drivers that provide | 122 | * Checks that a desired plane update is valid, and updates various |
123 | * bits of derived state (clipped coordinates etc.). Drivers that provide | ||
130 | * their own plane handling rather than helper-provided implementations may | 124 | * their own plane handling rather than helper-provided implementations may |
131 | * still wish to call this function to avoid duplication of error checking | 125 | * still wish to call this function to avoid duplication of error checking |
132 | * code. | 126 | * code. |
@@ -134,29 +128,38 @@ static int get_connectors_for_crtc(struct drm_crtc *crtc, | |||
134 | * RETURNS: | 128 | * RETURNS: |
135 | * Zero if update appears valid, error code on failure | 129 | * Zero if update appears valid, error code on failure |
136 | */ | 130 | */ |
137 | int drm_plane_helper_check_update(struct drm_plane *plane, | 131 | int drm_plane_helper_check_state(struct drm_plane_state *state, |
138 | struct drm_crtc *crtc, | 132 | const struct drm_rect *clip, |
139 | struct drm_framebuffer *fb, | 133 | int min_scale, |
140 | struct drm_rect *src, | 134 | int max_scale, |
141 | struct drm_rect *dest, | 135 | bool can_position, |
142 | const struct drm_rect *clip, | 136 | bool can_update_disabled) |
143 | unsigned int rotation, | ||
144 | int min_scale, | ||
145 | int max_scale, | ||
146 | bool can_position, | ||
147 | bool can_update_disabled, | ||
148 | bool *visible) | ||
149 | { | 137 | { |
138 | struct drm_crtc *crtc = state->crtc; | ||
139 | struct drm_framebuffer *fb = state->fb; | ||
140 | struct drm_rect *src = &state->src; | ||
141 | struct drm_rect *dst = &state->dst; | ||
142 | unsigned int rotation = state->rotation; | ||
150 | int hscale, vscale; | 143 | int hscale, vscale; |
151 | 144 | ||
145 | src->x1 = state->src_x; | ||
146 | src->y1 = state->src_y; | ||
147 | src->x2 = state->src_x + state->src_w; | ||
148 | src->y2 = state->src_y + state->src_h; | ||
149 | |||
150 | dst->x1 = state->crtc_x; | ||
151 | dst->y1 = state->crtc_y; | ||
152 | dst->x2 = state->crtc_x + state->crtc_w; | ||
153 | dst->y2 = state->crtc_y + state->crtc_h; | ||
154 | |||
152 | if (!fb) { | 155 | if (!fb) { |
153 | *visible = false; | 156 | state->visible = false; |
154 | return 0; | 157 | return 0; |
155 | } | 158 | } |
156 | 159 | ||
157 | /* crtc should only be NULL when disabling (i.e., !fb) */ | 160 | /* crtc should only be NULL when disabling (i.e., !fb) */ |
158 | if (WARN_ON(!crtc)) { | 161 | if (WARN_ON(!crtc)) { |
159 | *visible = false; | 162 | state->visible = false; |
160 | return 0; | 163 | return 0; |
161 | } | 164 | } |
162 | 165 | ||
@@ -168,20 +171,20 @@ int drm_plane_helper_check_update(struct drm_plane *plane, | |||
168 | drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation); | 171 | drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation); |
169 | 172 | ||
170 | /* Check scaling */ | 173 | /* Check scaling */ |
171 | hscale = drm_rect_calc_hscale(src, dest, min_scale, max_scale); | 174 | hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale); |
172 | vscale = drm_rect_calc_vscale(src, dest, min_scale, max_scale); | 175 | vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale); |
173 | if (hscale < 0 || vscale < 0) { | 176 | if (hscale < 0 || vscale < 0) { |
174 | DRM_DEBUG_KMS("Invalid scaling of plane\n"); | 177 | DRM_DEBUG_KMS("Invalid scaling of plane\n"); |
175 | drm_rect_debug_print("src: ", src, true); | 178 | drm_rect_debug_print("src: ", &state->src, true); |
176 | drm_rect_debug_print("dst: ", dest, false); | 179 | drm_rect_debug_print("dst: ", &state->dst, false); |
177 | return -ERANGE; | 180 | return -ERANGE; |
178 | } | 181 | } |
179 | 182 | ||
180 | *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale); | 183 | state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale); |
181 | 184 | ||
182 | drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation); | 185 | drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation); |
183 | 186 | ||
184 | if (!*visible) | 187 | if (!state->visible) |
185 | /* | 188 | /* |
186 | * Plane isn't visible; some drivers can handle this | 189 | * Plane isn't visible; some drivers can handle this |
187 | * so we just return success here. Drivers that can't | 190 | * so we just return success here. Drivers that can't |
@@ -191,15 +194,87 @@ int drm_plane_helper_check_update(struct drm_plane *plane, | |||
191 | */ | 194 | */ |
192 | return 0; | 195 | return 0; |
193 | 196 | ||
194 | if (!can_position && !drm_rect_equals(dest, clip)) { | 197 | if (!can_position && !drm_rect_equals(dst, clip)) { |
195 | DRM_DEBUG_KMS("Plane must cover entire CRTC\n"); | 198 | DRM_DEBUG_KMS("Plane must cover entire CRTC\n"); |
196 | drm_rect_debug_print("dst: ", dest, false); | 199 | drm_rect_debug_print("dst: ", dst, false); |
197 | drm_rect_debug_print("clip: ", clip, false); | 200 | drm_rect_debug_print("clip: ", clip, false); |
198 | return -EINVAL; | 201 | return -EINVAL; |
199 | } | 202 | } |
200 | 203 | ||
201 | return 0; | 204 | return 0; |
202 | } | 205 | } |
206 | EXPORT_SYMBOL(drm_plane_helper_check_state); | ||
207 | |||
208 | /** | ||
209 | * drm_plane_helper_check_update() - Check plane update for validity | ||
210 | * @plane: plane object to update | ||
211 | * @crtc: owning CRTC of owning plane | ||
212 | * @fb: framebuffer to flip onto plane | ||
213 | * @src: source coordinates in 16.16 fixed point | ||
214 | * @dest: integer destination coordinates | ||
215 | * @clip: integer clipping coordinates | ||
216 | * @rotation: plane rotation | ||
217 | * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point | ||
218 | * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point | ||
219 | * @can_position: is it legal to position the plane such that it | ||
220 | * doesn't cover the entire crtc? This will generally | ||
221 | * only be false for primary planes. | ||
222 | * @can_update_disabled: can the plane be updated while the crtc | ||
223 | * is disabled? | ||
224 | * @visible: output parameter indicating whether plane is still visible after | ||
225 | * clipping | ||
226 | * | ||
227 | * Checks that a desired plane update is valid. Drivers that provide | ||
228 | * their own plane handling rather than helper-provided implementations may | ||
229 | * still wish to call this function to avoid duplication of error checking | ||
230 | * code. | ||
231 | * | ||
232 | * RETURNS: | ||
233 | * Zero if update appears valid, error code on failure | ||
234 | */ | ||
235 | int drm_plane_helper_check_update(struct drm_plane *plane, | ||
236 | struct drm_crtc *crtc, | ||
237 | struct drm_framebuffer *fb, | ||
238 | struct drm_rect *src, | ||
239 | struct drm_rect *dst, | ||
240 | const struct drm_rect *clip, | ||
241 | unsigned int rotation, | ||
242 | int min_scale, | ||
243 | int max_scale, | ||
244 | bool can_position, | ||
245 | bool can_update_disabled, | ||
246 | bool *visible) | ||
247 | { | ||
248 | struct drm_plane_state state = { | ||
249 | .plane = plane, | ||
250 | .crtc = crtc, | ||
251 | .fb = fb, | ||
252 | .src_x = src->x1, | ||
253 | .src_y = src->y1, | ||
254 | .src_w = drm_rect_width(src), | ||
255 | .src_h = drm_rect_height(src), | ||
256 | .crtc_x = dst->x1, | ||
257 | .crtc_y = dst->y1, | ||
258 | .crtc_w = drm_rect_width(dst), | ||
259 | .crtc_h = drm_rect_height(dst), | ||
260 | .rotation = rotation, | ||
261 | .visible = *visible, | ||
262 | }; | ||
263 | int ret; | ||
264 | |||
265 | ret = drm_plane_helper_check_state(&state, clip, | ||
266 | min_scale, max_scale, | ||
267 | can_position, | ||
268 | can_update_disabled); | ||
269 | if (ret) | ||
270 | return ret; | ||
271 | |||
272 | *src = state.src; | ||
273 | *dst = state.dst; | ||
274 | *visible = state.visible; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
203 | EXPORT_SYMBOL(drm_plane_helper_check_update); | 278 | EXPORT_SYMBOL(drm_plane_helper_check_update); |
204 | 279 | ||
205 | /** | 280 | /** |
diff --git a/include/drm/drm_plane_helper.h b/include/drm/drm_plane_helper.h index 0e0c3573cce0..fbc8ecb3e5e8 100644 --- a/include/drm/drm_plane_helper.h +++ b/include/drm/drm_plane_helper.h | |||
@@ -40,6 +40,11 @@ | |||
40 | int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, | 40 | int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, |
41 | const struct drm_crtc_funcs *funcs); | 41 | const struct drm_crtc_funcs *funcs); |
42 | 42 | ||
43 | int drm_plane_helper_check_state(struct drm_plane_state *state, | ||
44 | const struct drm_rect *clip, | ||
45 | int min_scale, int max_scale, | ||
46 | bool can_position, | ||
47 | bool can_update_disabled); | ||
43 | int drm_plane_helper_check_update(struct drm_plane *plane, | 48 | int drm_plane_helper_check_update(struct drm_plane *plane, |
44 | struct drm_crtc *crtc, | 49 | struct drm_crtc *crtc, |
45 | struct drm_framebuffer *fb, | 50 | struct drm_framebuffer *fb, |