[RFC 1/3] drm: Add DAMAGE_CLIPS property to plane
From: Lukasz Spintzyk <lukasz.spint...@displaylink.com> Optional plane property to mark damaged regions on the plane in framebuffer coordinates of the framebuffer attached to the plane. The layout of blob data is simply an array of drm_mode_rect with maximum array size limited by DRM_MODE_FB_DIRTY_MAX_CLIPS. Unlike plane src coordinates, damage clips are not in 16.16 fixed point. Damage clips are a hint to kernel as which area of framebuffer has changed since last page-flip. This should be helpful for some drivers especially for virtual devices where each framebuffer change needs to be transmitted over network, usb, etc. Driver which are interested in enabling DAMAGE_CLIPS property for a plane should enable this property using drm_plane_enable_damage_clips. Signed-off-by: Lukasz Spintzyk <lukasz.spint...@displaylink.com> Signed-off-by: Deepak Rawat <dra...@vmware.com> --- drivers/gpu/drm/drm_atomic.c| 42 + drivers/gpu/drm/drm_atomic_helper.c | 4 drivers/gpu/drm/drm_mode_config.c | 5 + drivers/gpu/drm/drm_plane.c | 12 +++ include/drm/drm_mode_config.h | 15 + include/drm/drm_plane.h | 16 ++ include/uapi/drm/drm_mode.h | 15 + 7 files changed, 109 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 7d25c42..9226d24 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -669,6 +669,40 @@ static void drm_atomic_crtc_print_state(struct drm_printer *p, } /** + * drm_atomic_set_damage_for_plane - sets the damage clips property to plane + * @state: plane state + * @blob: damage clips in framebuffer coordinates + * + * Returns: + * + * Zero on success, error code on failure. + */ +static int drm_atomic_set_damage_for_plane(struct drm_plane_state *state, + struct drm_property_blob *blob) +{ + if (blob == state->damage_clips) + return 0; + + drm_property_blob_put(state->damage_clips); + state->damage_clips = NULL; + + if (blob) { + uint32_t count = blob->length/sizeof(struct drm_rect); + + if (count > DRM_MODE_FB_DIRTY_MAX_CLIPS) + return -EINVAL; + + state->damage_clips = drm_property_blob_get(blob); + state->num_clips = count; + } else { + state->damage_clips = NULL; + state->num_clips = 0; + } + + return 0; +} + +/** * drm_atomic_get_plane_state - get plane state * @state: global atomic state object * @plane: plane to get state object for @@ -793,6 +827,12 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->color_encoding = val; } else if (property == plane->color_range_property) { state->color_range = val; + } else if (property == config->prop_damage_clips) { + struct drm_property_blob *blob = + drm_property_lookup_blob(dev, val); + int ret = drm_atomic_set_damage_for_plane(state, blob); + drm_property_blob_put(blob); + return ret; } else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val); @@ -856,6 +896,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->color_encoding; } else if (property == plane->color_range_property) { *val = state->color_range; + } else if (property == config->prop_damage_clips) { + *val = (state->damage_clips) ? state->damage_clips->base.id : 0; } else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index c356545..55b44e3 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3506,6 +3506,8 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, state->fence = NULL; state->commit = NULL; + state->damage_clips = NULL; + state->num_clips = 0; } EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); @@ -3550,6 +3552,8 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) if (state->commit) drm_crtc_commit_put(state->commit); + + drm_property_blob_put(state->damage_clips); } EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index e5c6533..e93b127 100644 --- a/drivers/gpu/drm/dr
[RFC 1/3] drm: Add DAMAGE_CLIPS property to plane
From: Lukasz Spintzyk Optional plane property to mark damaged regions on the plane in framebuffer coordinates of the framebuffer attached to the plane. The layout of blob data is simply an array of drm_mode_rect with maximum array size limited by DRM_MODE_FB_DIRTY_MAX_CLIPS. Unlike plane src coordinates, damage clips are not in 16.16 fixed point. Damage clips are a hint to kernel as which area of framebuffer has changed since last page-flip. This should be helpful for some drivers especially for virtual devices where each framebuffer change needs to be transmitted over network, usb, etc. Driver which are interested in enabling DAMAGE_CLIPS property for a plane should enable this property using drm_plane_enable_damage_clips. Signed-off-by: Lukasz Spintzyk Signed-off-by: Deepak Rawat --- drivers/gpu/drm/drm_atomic.c| 42 + drivers/gpu/drm/drm_atomic_helper.c | 4 drivers/gpu/drm/drm_mode_config.c | 5 + drivers/gpu/drm/drm_plane.c | 12 +++ include/drm/drm_mode_config.h | 15 + include/drm/drm_plane.h | 16 ++ include/uapi/drm/drm_mode.h | 15 + 7 files changed, 109 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 7d25c42..9226d24 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -669,6 +669,40 @@ static void drm_atomic_crtc_print_state(struct drm_printer *p, } /** + * drm_atomic_set_damage_for_plane - sets the damage clips property to plane + * @state: plane state + * @blob: damage clips in framebuffer coordinates + * + * Returns: + * + * Zero on success, error code on failure. + */ +static int drm_atomic_set_damage_for_plane(struct drm_plane_state *state, + struct drm_property_blob *blob) +{ + if (blob == state->damage_clips) + return 0; + + drm_property_blob_put(state->damage_clips); + state->damage_clips = NULL; + + if (blob) { + uint32_t count = blob->length/sizeof(struct drm_rect); + + if (count > DRM_MODE_FB_DIRTY_MAX_CLIPS) + return -EINVAL; + + state->damage_clips = drm_property_blob_get(blob); + state->num_clips = count; + } else { + state->damage_clips = NULL; + state->num_clips = 0; + } + + return 0; +} + +/** * drm_atomic_get_plane_state - get plane state * @state: global atomic state object * @plane: plane to get state object for @@ -793,6 +827,12 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, state->color_encoding = val; } else if (property == plane->color_range_property) { state->color_range = val; + } else if (property == config->prop_damage_clips) { + struct drm_property_blob *blob = + drm_property_lookup_blob(dev, val); + int ret = drm_atomic_set_damage_for_plane(state, blob); + drm_property_blob_put(blob); + return ret; } else if (plane->funcs->atomic_set_property) { return plane->funcs->atomic_set_property(plane, state, property, val); @@ -856,6 +896,8 @@ drm_atomic_plane_get_property(struct drm_plane *plane, *val = state->color_encoding; } else if (property == plane->color_range_property) { *val = state->color_range; + } else if (property == config->prop_damage_clips) { + *val = (state->damage_clips) ? state->damage_clips->base.id : 0; } else if (plane->funcs->atomic_get_property) { return plane->funcs->atomic_get_property(plane, state, property, val); } else { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index c356545..55b44e3 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3506,6 +3506,8 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, state->fence = NULL; state->commit = NULL; + state->damage_clips = NULL; + state->num_clips = 0; } EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); @@ -3550,6 +3552,8 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) if (state->commit) drm_crtc_commit_put(state->commit); + + drm_property_blob_put(state->damage_clips); } EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index e5c6533..e93b127 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -293,6 +293,11 @@ static int
[RFC 2/3] drm: Add helper iterator functions to iterate over plane damage.
With damage property in drm_plane_state, this patch adds helper iterator to traverse the damage clips. Iterator will return the damage rectangles in framebuffer, plane or crtc coordinates as need by driver implementation. Signed-off-by: Deepak Rawat <dra...@vmware.com> --- drivers/gpu/drm/drm_atomic_helper.c | 122 include/drm/drm_atomic_helper.h | 39 2 files changed, 161 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 55b44e3..355b514 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3865,3 +3865,125 @@ void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj memcpy(state, obj->state, sizeof(*state)); } EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state); + +/** + * drm_atomic_helper_damage_iter_init - initialize the damage iterator + * @iter: The iterator to initialize. + * @type: Coordinate type caller is interested in. + * @state: plane_state from which to iterate the damage clips. + * @hdisplay: Width of crtc on which plane is scanned out. + * @vdisplay: Height of crtc on which plane is scanned out. + * + * Initialize an iterator that is used to translate and clip a set of damage + * rectangles in framebuffer coordinates to plane and crtc coordinates. The type + * argument specify which type of coordinate to iterate in. + * + * Returns: 0 on success and negative error code on error. If an error code is + * returned then it means the plane state should not update. + */ +int +drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, + enum drm_atomic_helper_damage_clip_type type, + const struct drm_plane_state *state, + uint32_t hdisplay, uint32_t vdisplay) +{ + if (!state || !state->crtc || !state->fb) + return -EINVAL; + + memset(iter, 0, sizeof(*iter)); + iter->clips = (struct drm_rect *)state->damage_clips->data; + iter->num_clips = state->num_clips; + iter->type = type; + + /* +* Full update in case of scaling or rotation. In future support for +* scaling/rotating damage clips can be added +*/ + if (state->crtc_w != (state->src_w >> 16) || + state->crtc_h != state->src_h >> 16 || state->rotation != 0) { + iter->curr_clip = iter->num_clips; + return 0; + } + + iter->fb_src.x1 = 0; + iter->fb_src.y1 = 0; + iter->fb_src.x2 = state->fb->width; + iter->fb_src.y2 = state->fb->height; + + iter->plane_src.x1 = state->src_x >> 16; + iter->plane_src.y1 = state->src_y >> 16; + iter->plane_src.x2 = iter->plane_src.x1 + (state->src_w >> 16); + iter->plane_src.y2 = iter->plane_src.y1 + (state->src_h >> 16); + iter->translate_plane_x = -iter->plane_src.x1; + iter->translate_plane_y = -iter->plane_src.y1; + + /* Clip plane src rect to fb dimensions */ + drm_rect_intersect(>plane_src, >fb_src); + + iter->crtc_src.x1 = 0; + iter->crtc_src.y1 = 0; + iter->crtc_src.x2 = hdisplay; + iter->crtc_src.y2 = vdisplay; + iter->translate_crtc_x = -(iter->plane_src.x1 - state->crtc_x); + iter->translate_crtc_x = -(iter->plane_src.y1 - state->crtc_y); + + /* Clip crtc src rect to plane dimensions */ + drm_rect_translate(>crtc_src, -iter->translate_crtc_x, + -iter->translate_crtc_x); + drm_rect_intersect(>crtc_src, >plane_src); + + return 0; +} +EXPORT_SYMBOL(drm_atomic_helper_damage_iter_init); + +/** + * drm_atomic_helper_damage_iter_next - advance the damage iterator + * @iter: The iterator to advance. + * @rect: Return a rectangle in coordinate specified during iterator init. + * + * Returns: true if the output is valid, false if we've reached the end of the + * rectangle list. If the first call return false, means need full update. + */ +bool +drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, + struct drm_rect *rect) +{ + const struct drm_rect *curr_clip; + +next_clip: + if (iter->curr_clip >= iter->num_clips) + return false; + + curr_clip = >clips[iter->curr_clip]; + iter->curr_clip++; + + rect->x1 = curr_clip->x1; + rect->x2 = curr_clip->x2; + rect->y1 = curr_clip->y1; + rect->y2 = curr_clip->y2; + + /* Clip damage rect within fb limit */ + if (!drm_rect_intersect(rect, >fb_src)) + goto next_clip; +
[RFC 2/3] drm: Add helper iterator functions to iterate over plane damage.
With damage property in drm_plane_state, this patch adds helper iterator to traverse the damage clips. Iterator will return the damage rectangles in framebuffer, plane or crtc coordinates as need by driver implementation. Signed-off-by: Deepak Rawat --- drivers/gpu/drm/drm_atomic_helper.c | 122 include/drm/drm_atomic_helper.h | 39 2 files changed, 161 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 55b44e3..355b514 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3865,3 +3865,125 @@ void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj memcpy(state, obj->state, sizeof(*state)); } EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state); + +/** + * drm_atomic_helper_damage_iter_init - initialize the damage iterator + * @iter: The iterator to initialize. + * @type: Coordinate type caller is interested in. + * @state: plane_state from which to iterate the damage clips. + * @hdisplay: Width of crtc on which plane is scanned out. + * @vdisplay: Height of crtc on which plane is scanned out. + * + * Initialize an iterator that is used to translate and clip a set of damage + * rectangles in framebuffer coordinates to plane and crtc coordinates. The type + * argument specify which type of coordinate to iterate in. + * + * Returns: 0 on success and negative error code on error. If an error code is + * returned then it means the plane state should not update. + */ +int +drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, + enum drm_atomic_helper_damage_clip_type type, + const struct drm_plane_state *state, + uint32_t hdisplay, uint32_t vdisplay) +{ + if (!state || !state->crtc || !state->fb) + return -EINVAL; + + memset(iter, 0, sizeof(*iter)); + iter->clips = (struct drm_rect *)state->damage_clips->data; + iter->num_clips = state->num_clips; + iter->type = type; + + /* +* Full update in case of scaling or rotation. In future support for +* scaling/rotating damage clips can be added +*/ + if (state->crtc_w != (state->src_w >> 16) || + state->crtc_h != state->src_h >> 16 || state->rotation != 0) { + iter->curr_clip = iter->num_clips; + return 0; + } + + iter->fb_src.x1 = 0; + iter->fb_src.y1 = 0; + iter->fb_src.x2 = state->fb->width; + iter->fb_src.y2 = state->fb->height; + + iter->plane_src.x1 = state->src_x >> 16; + iter->plane_src.y1 = state->src_y >> 16; + iter->plane_src.x2 = iter->plane_src.x1 + (state->src_w >> 16); + iter->plane_src.y2 = iter->plane_src.y1 + (state->src_h >> 16); + iter->translate_plane_x = -iter->plane_src.x1; + iter->translate_plane_y = -iter->plane_src.y1; + + /* Clip plane src rect to fb dimensions */ + drm_rect_intersect(>plane_src, >fb_src); + + iter->crtc_src.x1 = 0; + iter->crtc_src.y1 = 0; + iter->crtc_src.x2 = hdisplay; + iter->crtc_src.y2 = vdisplay; + iter->translate_crtc_x = -(iter->plane_src.x1 - state->crtc_x); + iter->translate_crtc_x = -(iter->plane_src.y1 - state->crtc_y); + + /* Clip crtc src rect to plane dimensions */ + drm_rect_translate(>crtc_src, -iter->translate_crtc_x, + -iter->translate_crtc_x); + drm_rect_intersect(>crtc_src, >plane_src); + + return 0; +} +EXPORT_SYMBOL(drm_atomic_helper_damage_iter_init); + +/** + * drm_atomic_helper_damage_iter_next - advance the damage iterator + * @iter: The iterator to advance. + * @rect: Return a rectangle in coordinate specified during iterator init. + * + * Returns: true if the output is valid, false if we've reached the end of the + * rectangle list. If the first call return false, means need full update. + */ +bool +drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, + struct drm_rect *rect) +{ + const struct drm_rect *curr_clip; + +next_clip: + if (iter->curr_clip >= iter->num_clips) + return false; + + curr_clip = >clips[iter->curr_clip]; + iter->curr_clip++; + + rect->x1 = curr_clip->x1; + rect->x2 = curr_clip->x2; + rect->y1 = curr_clip->y1; + rect->y2 = curr_clip->y2; + + /* Clip damage rect within fb limit */ + if (!drm_rect_intersect(rect, >fb_src)) + goto next_clip; + else i
[RFC 3/3] drm: Add helper to validate damage during modeset_check
This patch adds a helper which should be called by driver which enable damage (by calling drm_plane_enable_damage_clips) from atomic_check hook. This helper for now set the damage to NULL for the planes on crtc which need full modeset. The driver also need to check for other crtc properties which can affect damage in atomic_check hook, like gamma, ctm, etc. Plane related properties which affect damage can be handled in damage iterator. Signed-off-by: Deepak Rawat <dra...@vmware.com> --- drivers/gpu/drm/drm_atomic_helper.c | 47 + include/drm/drm_atomic_helper.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 355b514..23f44ab 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3987,3 +3987,50 @@ drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, return true; } EXPORT_SYMBOL(drm_atomic_helper_damage_iter_next); + +/** + * drm_atomic_helper_check_damage - validate state object for damage changes + * @dev: DRM device + * @state: the driver state object + * + * Check the state object if damage is required or not. In case damage is not + * required e.g. need modeset, the damage blob is set to NULL. + * + * NOTE: This helper is not called by core. Those driver which enable damage + * using drm_plane_enable_damage_clips should call this from their @atomic_check + * hook. + */ +int drm_atomic_helper_check_damage(struct drm_device *dev, + struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_plane *plane; + struct drm_crtc_state *crtc_state; + unsigned plane_mask; + int i; + + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { + if (!drm_atomic_crtc_needs_modeset(crtc_state)) + continue; + + plane_mask = crtc_state->plane_mask; + plane_mask |= crtc->state->plane_mask; + + drm_for_each_plane_mask(plane, dev, plane_mask) { + struct drm_plane_state *plane_state = + drm_atomic_get_plane_state(state, plane); + + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + + if (plane_state->damage_clips) { + drm_property_blob_put(plane_state->damage_clips); + plane_state->damage_clips = NULL; + plane_state->num_clips = 0; + } + } + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_helper_check_damage); diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index ebd4b66..b12335c 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -224,6 +224,8 @@ drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, bool drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, struct drm_rect *rect); +int drm_atomic_helper_check_damage(struct drm_device *dev, + struct drm_atomic_state *state); /** * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC -- 2.7.4
[RFC 3/3] drm: Add helper to validate damage during modeset_check
This patch adds a helper which should be called by driver which enable damage (by calling drm_plane_enable_damage_clips) from atomic_check hook. This helper for now set the damage to NULL for the planes on crtc which need full modeset. The driver also need to check for other crtc properties which can affect damage in atomic_check hook, like gamma, ctm, etc. Plane related properties which affect damage can be handled in damage iterator. Signed-off-by: Deepak Rawat --- drivers/gpu/drm/drm_atomic_helper.c | 47 + include/drm/drm_atomic_helper.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 355b514..23f44ab 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -3987,3 +3987,50 @@ drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, return true; } EXPORT_SYMBOL(drm_atomic_helper_damage_iter_next); + +/** + * drm_atomic_helper_check_damage - validate state object for damage changes + * @dev: DRM device + * @state: the driver state object + * + * Check the state object if damage is required or not. In case damage is not + * required e.g. need modeset, the damage blob is set to NULL. + * + * NOTE: This helper is not called by core. Those driver which enable damage + * using drm_plane_enable_damage_clips should call this from their @atomic_check + * hook. + */ +int drm_atomic_helper_check_damage(struct drm_device *dev, + struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_plane *plane; + struct drm_crtc_state *crtc_state; + unsigned plane_mask; + int i; + + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { + if (!drm_atomic_crtc_needs_modeset(crtc_state)) + continue; + + plane_mask = crtc_state->plane_mask; + plane_mask |= crtc->state->plane_mask; + + drm_for_each_plane_mask(plane, dev, plane_mask) { + struct drm_plane_state *plane_state = + drm_atomic_get_plane_state(state, plane); + + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + + if (plane_state->damage_clips) { + drm_property_blob_put(plane_state->damage_clips); + plane_state->damage_clips = NULL; + plane_state->num_clips = 0; + } + } + } + + return 0; +} +EXPORT_SYMBOL(drm_atomic_helper_check_damage); diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index ebd4b66..b12335c 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -224,6 +224,8 @@ drm_atomic_helper_damage_iter_init(struct drm_atomic_helper_damage_iter *iter, bool drm_atomic_helper_damage_iter_next(struct drm_atomic_helper_damage_iter *iter, struct drm_rect *rect); +int drm_atomic_helper_check_damage(struct drm_device *dev, + struct drm_atomic_state *state); /** * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC -- 2.7.4
[RFC 0/3] drm: page-flip with damage
Hi All, This is extension to Lukasz Spintzyk earlier draft of damage interface for drm. Bascially a new plane property is added called "DAMAGE_CLIPS" which is simply an array of drm_rect (exported to userspace as drm_mode_rect). The clips represents damage in framebuffer coordinate of attached fb to the plane. Helper iterator is added to traverse the damage rectangles and get the damage clips in framebuffer, plane or crtc coordinates as need by driver implementation. Finally a helper to reset damage in case need full update is required. Drivers interested in page-flip with damage should call this from atomic_check hook. With the RFC for atomic implementation of dirtyfb ioctl I was thinking should we need to consider dirty_fb flags, especially DRM_MODE_FB_DIRTY_ANNOTATE_COPY to be passed with atomic DAMAGE_CLIPS property blob? I didn't considered that untill now. If no driver uses that in my opinion for simplicity this can be ignored? About overlaping of damage rectangles is also not finalized. This really depends on driver specific implementation and can be left open-ended? My knowledge is limited to vmwgfx so would like to hear about other driver use cases and this can be modified in keeping other drivers need. Going forward driver implementation for vmwgfx and user-space implementation of kmscube/weston will be next step to test the changes. Thanks, Deepak Deepak Rawat (2): drm: Add helper iterator functions to iterate over plane damage. drm: Add helper to validate damage during modeset_check Lukasz Spintzyk (1): drm: Add DAMAGE_CLIPS property to plane drivers/gpu/drm/drm_atomic.c| 42 + drivers/gpu/drm/drm_atomic_helper.c | 173 drivers/gpu/drm/drm_mode_config.c | 5 ++ drivers/gpu/drm/drm_plane.c | 12 +++ include/drm/drm_atomic_helper.h | 41 + include/drm/drm_mode_config.h | 15 include/drm/drm_plane.h | 16 include/uapi/drm/drm_mode.h | 15 8 files changed, 319 insertions(+) -- 2.7.4
[RFC 0/3] drm: page-flip with damage
Hi All, This is extension to Lukasz Spintzyk earlier draft of damage interface for drm. Bascially a new plane property is added called "DAMAGE_CLIPS" which is simply an array of drm_rect (exported to userspace as drm_mode_rect). The clips represents damage in framebuffer coordinate of attached fb to the plane. Helper iterator is added to traverse the damage rectangles and get the damage clips in framebuffer, plane or crtc coordinates as need by driver implementation. Finally a helper to reset damage in case need full update is required. Drivers interested in page-flip with damage should call this from atomic_check hook. With the RFC for atomic implementation of dirtyfb ioctl I was thinking should we need to consider dirty_fb flags, especially DRM_MODE_FB_DIRTY_ANNOTATE_COPY to be passed with atomic DAMAGE_CLIPS property blob? I didn't considered that untill now. If no driver uses that in my opinion for simplicity this can be ignored? About overlaping of damage rectangles is also not finalized. This really depends on driver specific implementation and can be left open-ended? My knowledge is limited to vmwgfx so would like to hear about other driver use cases and this can be modified in keeping other drivers need. Going forward driver implementation for vmwgfx and user-space implementation of kmscube/weston will be next step to test the changes. Thanks, Deepak Deepak Rawat (2): drm: Add helper iterator functions to iterate over plane damage. drm: Add helper to validate damage during modeset_check Lukasz Spintzyk (1): drm: Add DAMAGE_CLIPS property to plane drivers/gpu/drm/drm_atomic.c| 42 + drivers/gpu/drm/drm_atomic_helper.c | 173 drivers/gpu/drm/drm_mode_config.c | 5 ++ drivers/gpu/drm/drm_plane.c | 12 +++ include/drm/drm_atomic_helper.h | 41 + include/drm/drm_mode_config.h | 15 include/drm/drm_plane.h | 16 include/uapi/drm/drm_mode.h | 15 8 files changed, 319 insertions(+) -- 2.7.4