drm/nouveau/kms/nv50-: plane updates don't always require image_set()
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 May 2018 10:39:47 +0000 (20:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 18 May 2018 05:01:29 +0000 (15:01 +1000)
When only the position of a window changes, there's no need to submit
an image update as well.

Will be required to support the overlays, and Volta windows.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/base507c.c
drivers/gpu/drm/nouveau/dispnv50/wndw.c

index 819403f4b958d0ad9caa6114c0d69309b1713b0c..d8d35166936761b7f016027d7562a4f44d11c4b3 100644 (file)
@@ -185,7 +185,6 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
        asyh->base.h = asyw->state.fb->height;
 
        asyw->lut.enable = 1;
-       asyw->set.image = true;
        return 0;
 }
 
index 4a685d78ed339d4da8315e5f688d5d11e3b3e612..0f6de6049be4412f9accf9eb1f637d22589ffde3 100644 (file)
@@ -190,7 +190,8 @@ nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
 }
 
 static int
-nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw,
+nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
+                              struct nv50_wndw_atom *armw,
                               struct nv50_wndw_atom *asyw,
                               struct nv50_head_atom *asyh)
 {
@@ -200,40 +201,44 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw,
 
        NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name);
 
-       asyw->image.w = fb->base.width;
-       asyw->image.h = fb->base.height;
-       asyw->image.kind = fb->nvbo->kind;
+       if (asyw->state.fb != armw->state.fb || !armw->visible || modeset) {
+               asyw->image.w = fb->base.width;
+               asyw->image.h = fb->base.height;
+               asyw->image.kind = fb->nvbo->kind;
 
-       ret = nv50_wndw_atomic_check_acquire_rgb(asyw);
-       if (ret)
-               return ret;
-
-       if (asyw->image.kind) {
-               asyw->image.layout = 0;
-               if (drm->client.device.info.chipset >= 0xc0)
-                       asyw->image.block = fb->nvbo->mode >> 4;
-               else
-                       asyw->image.block = fb->nvbo->mode;
-               asyw->image.pitch[0] = (fb->base.pitches[0] / 4) << 4;
-       } else {
-               asyw->image.layout = 1;
-               asyw->image.block  = 0;
-               asyw->image.pitch[0] = fb->base.pitches[0];
-       }
+               ret = nv50_wndw_atomic_check_acquire_rgb(asyw);
+               if (ret)
+                       return ret;
 
-       ret = wndw->func->acquire(wndw, asyw, asyh);
-       if (ret)
-               return ret;
+               if (asyw->image.kind) {
+                       asyw->image.layout = 0;
+                       if (drm->client.device.info.chipset >= 0xc0)
+                               asyw->image.block = fb->nvbo->mode >> 4;
+                       else
+                               asyw->image.block = fb->nvbo->mode;
+                       asyw->image.pitch[0] = (fb->base.pitches[0] / 4) << 4;
+               } else {
+                       asyw->image.layout = 1;
+                       asyw->image.block  = 0;
+                       asyw->image.pitch[0] = fb->base.pitches[0];
+               }
 
-       if (asyw->set.image) {
                if (!(asyh->state.pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC))
                        asyw->image.interval = 1;
                else
                        asyw->image.interval = 0;
                asyw->image.mode = asyw->image.interval ? 0 : 1;
+               asyw->set.image = wndw->func->image_set != NULL;
        }
 
-       return 0;
+       if (wndw->immd) {
+               asyw->point.x = asyw->state.crtc_x;
+               asyw->point.y = asyw->state.crtc_y;
+               if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point)))
+                       asyw->set.point = true;
+       }
+
+       return wndw->func->acquire(wndw, asyw, asyh);
 }
 
 int
@@ -271,12 +276,8 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
 
        /* Calculate new window state. */
        if (asyw->visible) {
-               asyw->point.x = asyw->state.crtc_x;
-               asyw->point.y = asyw->state.crtc_y;
-               if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point)))
-                       asyw->set.point = true;
-
-               ret = nv50_wndw_atomic_check_acquire(wndw, asyw, asyh);
+               ret = nv50_wndw_atomic_check_acquire(wndw, modeset,
+                                                    armw, asyw, asyh);
                if (ret)
                        return ret;
        } else