drm/gem: Implement shadow-plane {begin, end}_fb_access with vmap

Move the vmap code for shadow-plane helpers from prepare_fb to
begin_fb_access helpers. Vunmap is now performed at the end of
the current pageflip, instead of the end of the following pageflip.

Reduces the duration of the mapping from while the framebuffer is
being displayed to just the atomic commit. This is safe as outside
of the pageflip, nothing should access the mapped buffer memory.
Unmapping the framebuffer BO memory early allows to reduce address-
space consumption and possibly allows for evicting the memory pages.

The change is effectively a rename of prepare_fb and cleanup_fb
implementations, plus updates to the shadow-plane init macro. As
there's no longer a prepare_fb helper for shadow planes, atomic
helpers will call drm_gem_plane_helper_prepare_fb() automatically.

v2:
	* fix typos in commit message (Javier)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221025101737.8874-3-tzimmermann@suse.de
This commit is contained in:
Thomas Zimmermann 2022-10-25 12:17:37 +02:00
parent 94d879eaf7
commit 359c6649cd
2 changed files with 31 additions and 36 deletions

View File

@ -360,48 +360,43 @@ void drm_gem_reset_shadow_plane(struct drm_plane *plane)
EXPORT_SYMBOL(drm_gem_reset_shadow_plane);
/**
* drm_gem_prepare_shadow_fb - prepares shadow framebuffers
* drm_gem_begin_shadow_fb_access - prepares shadow framebuffers for CPU access
* @plane: the plane
* @plane_state: the plane state of type struct drm_shadow_plane_state
*
* This function implements struct &drm_plane_helper_funcs.prepare_fb. It
* This function implements struct &drm_plane_helper_funcs.begin_fb_access. It
* maps all buffer objects of the plane's framebuffer into kernel address
* space and stores them in &struct drm_shadow_plane_state.map. The
* framebuffer will be synchronized as part of the atomic commit.
* space and stores them in struct &drm_shadow_plane_state.map. The first data
* bytes are available in struct &drm_shadow_plane_state.data.
*
* See drm_gem_cleanup_shadow_fb() for cleanup.
* See drm_gem_end_shadow_fb_access() for cleanup.
*
* Returns:
* 0 on success, or a negative errno code otherwise.
*/
int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *plane_state)
int drm_gem_begin_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state)
{
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_framebuffer *fb = plane_state->fb;
int ret;
if (!fb)
return 0;
ret = drm_gem_plane_helper_prepare_fb(plane, plane_state);
if (ret)
return ret;
return drm_gem_fb_vmap(fb, shadow_plane_state->map, shadow_plane_state->data);
}
EXPORT_SYMBOL(drm_gem_prepare_shadow_fb);
EXPORT_SYMBOL(drm_gem_begin_shadow_fb_access);
/**
* drm_gem_cleanup_shadow_fb - releases shadow framebuffers
* drm_gem_end_shadow_fb_access - releases shadow framebuffers from CPU access
* @plane: the plane
* @plane_state: the plane state of type struct drm_shadow_plane_state
*
* This function implements struct &drm_plane_helper_funcs.cleanup_fb.
* This function unmaps all buffer objects of the plane's framebuffer.
* This function implements struct &drm_plane_helper_funcs.end_fb_access. It
* undoes all effects of drm_gem_begin_shadow_fb_access() in reverse order.
*
* See drm_gem_prepare_shadow_fb() for more information.
* See drm_gem_begin_shadow_fb_access() for more information.
*/
void drm_gem_cleanup_shadow_fb(struct drm_plane *plane, struct drm_plane_state *plane_state)
void drm_gem_end_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state)
{
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
struct drm_framebuffer *fb = plane_state->fb;
@ -411,7 +406,7 @@ void drm_gem_cleanup_shadow_fb(struct drm_plane *plane, struct drm_plane_state *
drm_gem_fb_vunmap(fb, shadow_plane_state->map);
}
EXPORT_SYMBOL(drm_gem_cleanup_shadow_fb);
EXPORT_SYMBOL(drm_gem_end_shadow_fb_access);
/**
* drm_gem_simple_kms_begin_shadow_fb_access - prepares shadow framebuffers for CPU access
@ -426,12 +421,12 @@ EXPORT_SYMBOL(drm_gem_cleanup_shadow_fb);
* Returns:
* 0 on success, or a negative errno code otherwise.
*/
int drm_gem_simple_kms_prepare_shadow_fb(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state)
int drm_gem_simple_kms_begin_shadow_fb_access(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state)
{
return drm_gem_prepare_shadow_fb(&pipe->plane, plane_state);
return drm_gem_begin_shadow_fb_access(&pipe->plane, plane_state);
}
EXPORT_SYMBOL(drm_gem_simple_kms_prepare_shadow_fb);
EXPORT_SYMBOL(drm_gem_simple_kms_begin_shadow_fb_access);
/**
* drm_gem_simple_kms_end_shadow_fb_access - releases shadow framebuffers from CPU access
@ -444,12 +439,12 @@ EXPORT_SYMBOL(drm_gem_simple_kms_prepare_shadow_fb);
*
* See drm_gem_simple_kms_begin_shadow_fb_access().
*/
void drm_gem_simple_kms_cleanup_shadow_fb(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state)
void drm_gem_simple_kms_end_shadow_fb_access(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state)
{
drm_gem_cleanup_shadow_fb(&pipe->plane, plane_state);
drm_gem_end_shadow_fb_access(&pipe->plane, plane_state);
}
EXPORT_SYMBOL(drm_gem_simple_kms_cleanup_shadow_fb);
EXPORT_SYMBOL(drm_gem_simple_kms_end_shadow_fb_access);
/**
* drm_gem_simple_kms_reset_shadow_plane - resets a shadow-buffered plane

View File

@ -103,8 +103,8 @@ void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane,
.atomic_duplicate_state = drm_gem_duplicate_shadow_plane_state, \
.atomic_destroy_state = drm_gem_destroy_shadow_plane_state
int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *plane_state);
void drm_gem_cleanup_shadow_fb(struct drm_plane *plane, struct drm_plane_state *plane_state);
int drm_gem_begin_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state);
void drm_gem_end_shadow_fb_access(struct drm_plane *plane, struct drm_plane_state *plane_state);
/**
* DRM_GEM_SHADOW_PLANE_HELPER_FUNCS -
@ -115,13 +115,13 @@ void drm_gem_cleanup_shadow_fb(struct drm_plane *plane, struct drm_plane_state *
* functions.
*/
#define DRM_GEM_SHADOW_PLANE_HELPER_FUNCS \
.prepare_fb = drm_gem_prepare_shadow_fb, \
.cleanup_fb = drm_gem_cleanup_shadow_fb
.begin_fb_access = drm_gem_begin_shadow_fb_access, \
.end_fb_access = drm_gem_end_shadow_fb_access
int drm_gem_simple_kms_prepare_shadow_fb(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state);
void drm_gem_simple_kms_cleanup_shadow_fb(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state);
int drm_gem_simple_kms_begin_shadow_fb_access(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state);
void drm_gem_simple_kms_end_shadow_fb_access(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *plane_state);
void drm_gem_simple_kms_reset_shadow_plane(struct drm_simple_display_pipe *pipe);
struct drm_plane_state *
drm_gem_simple_kms_duplicate_shadow_plane_state(struct drm_simple_display_pipe *pipe);
@ -137,8 +137,8 @@ void drm_gem_simple_kms_destroy_shadow_plane_state(struct drm_simple_display_pip
* functions.
*/
#define DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS \
.prepare_fb = drm_gem_simple_kms_prepare_shadow_fb, \
.cleanup_fb = drm_gem_simple_kms_cleanup_shadow_fb, \
.begin_fb_access = drm_gem_simple_kms_begin_shadow_fb_access, \
.end_fb_access = drm_gem_simple_kms_end_shadow_fb_access, \
.reset_plane = drm_gem_simple_kms_reset_shadow_plane, \
.duplicate_plane_state = drm_gem_simple_kms_duplicate_shadow_plane_state, \
.destroy_plane_state = drm_gem_simple_kms_destroy_shadow_plane_state