diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2018-05-08 13:39:47 +0300 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2018-05-18 08:01:29 +0300 |
commit | 859b456b6b19a19761883cf52993dec645a36152 (patch) | |
tree | 47491de6b1fed7a33698a00d5fbad88cfd917ccd /drivers | |
parent | 45a2945a3759479c08a4aceaee181639c92f9d48 (diff) | |
download | linux-859b456b6b19a19761883cf52993dec645a36152.tar.xz |
drm/nouveau/kms/nv50-: store window visibility in state
Window visibility is going to become a little more complicated with the
upcoming LUT changes, so store the calculated value to avoid needing to
recalculate the armed state again.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv50/atom.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/dispnv50/wndw.c | 27 |
2 files changed, 21 insertions, 8 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv50/atom.h b/drivers/gpu/drm/nouveau/dispnv50/atom.h index b5b8a12a18f2..fefb9caaf7b8 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/atom.h +++ b/drivers/gpu/drm/nouveau/dispnv50/atom.h @@ -136,6 +136,8 @@ nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) struct nv50_wndw_atom { struct drm_plane_state state; + bool visible; + struct { u32 handle; u16 offset:12; diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 06d1696b7d03..4a685d78ed33 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -244,26 +244,33 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) struct nv50_wndw_atom *armw = nv50_wndw_atom(wndw->plane.state); struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); struct nv50_head_atom *harm = NULL, *asyh = NULL; - bool varm = false, asyv = false, asym = false; + bool modeset = false; int ret; NV_ATOMIC(drm, "%s atomic_check\n", plane->name); + + /* Fetch the assembly state for the head the window will belong to, + * and determine whether the window will be visible. + */ if (asyw->state.crtc) { asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); if (IS_ERR(asyh)) return PTR_ERR(asyh); - asym = drm_atomic_crtc_needs_modeset(&asyh->state); - asyv = asyh->state.active; + modeset = drm_atomic_crtc_needs_modeset(&asyh->state); + asyw->visible = asyh->state.active; + } else { + asyw->visible = false; } + /* Fetch assembly state for the head the window used to belong to. */ if (armw->state.crtc) { harm = nv50_head_atom_get(asyw->state.state, armw->state.crtc); if (IS_ERR(harm)) return PTR_ERR(harm); - varm = harm->state.crtc->state->active; } - if (asyv) { + /* 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))) @@ -273,18 +280,22 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) if (ret) return ret; } else - if (varm) { + if (armw->visible) { nv50_wndw_atomic_check_release(wndw, asyw, harm); } else { return 0; } - if (!asyv || asym) { + /* Aside from the obvious case where the window is actively being + * disabled, we might also need to temporarily disable the window + * when performing certain modeset operations. + */ + if (!asyw->visible || modeset) { asyw->clr.ntfy = armw->ntfy.handle != 0; asyw->clr.sema = armw->sema.handle != 0; if (wndw->func->image_clr) asyw->clr.image = armw->image.handle[0] != 0; - asyw->set.lut = wndw->func->lut && asyv; + asyw->set.lut = wndw->func->lut && asyw->visible; } return 0; |