drm/ofdrm: Preallocate format-conversion buffer in atomic_check
authorThomas Zimmermann <tzimmermann@suse.de>
Mon, 9 Oct 2023 14:06:33 +0000 (16:06 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Tue, 14 Nov 2023 09:17:22 +0000 (10:17 +0100)
Preallocate the format-conversion state's storage in the plane's
atomic_check function if a format conversion is necessary. Allows
the update to fail if no memory is available. Avoids the same
allocation within atomic_update, which may not fail.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231009141018.11291-5-tzimmermann@suse.de
drivers/gpu/drm/tiny/ofdrm.c

index 404c83032cecc6998a3ab4f1147d3c1c91671be6..05a72473cfc65e2cfeb3a46c6985621d035be297 100644 (file)
@@ -758,7 +758,11 @@ static const uint64_t ofdrm_primary_plane_format_modifiers[] = {
 static int ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
                                                   struct drm_atomic_state *new_state)
 {
+       struct drm_device *dev = plane->dev;
+       struct ofdrm_device *odev = ofdrm_device_of_dev(dev);
        struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(new_state, plane);
+       struct drm_shadow_plane_state *new_shadow_plane_state =
+               to_drm_shadow_plane_state(new_plane_state);
        struct drm_framebuffer *new_fb = new_plane_state->fb;
        struct drm_crtc *new_crtc = new_plane_state->crtc;
        struct drm_crtc_state *new_crtc_state = NULL;
@@ -777,6 +781,16 @@ static int ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
        else if (!new_plane_state->visible)
                return 0;
 
+       if (new_fb->format != odev->format) {
+               void *buf;
+
+               /* format conversion necessary; reserve buffer */
+               buf = drm_format_conv_state_reserve(&new_shadow_plane_state->fmtcnv_state,
+                                                   odev->pitch, GFP_KERNEL);
+               if (!buf)
+                       return -ENOMEM;
+       }
+
        new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_plane_state->crtc);
 
        new_ofdrm_crtc_state = to_ofdrm_crtc_state(new_crtc_state);