Commit 58d09ebd authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Fix the overlay frontbuffer tracking

Do the overlay frontbuffer tracking properly so that it matches
the state of the overlay on/off/continue requests.

One slight problem is that intel_frontbuffer_flip_complete()
may get delayed by an arbitrarily liong time due to the fact that
the overlay code likes to bail out when a signal occurs. So the
flip may not get completed until the ioctl is restarted. But fixing
that would require bigger surgery, so I decided to ignore it for now.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1481131693-27993-5-git-send-email-ville.syrjala@linux.intel.comReviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 4a15cdbb
...@@ -272,8 +272,30 @@ static int intel_overlay_on(struct intel_overlay *overlay) ...@@ -272,8 +272,30 @@ static int intel_overlay_on(struct intel_overlay *overlay)
return intel_overlay_do_wait_request(overlay, req, NULL); return intel_overlay_do_wait_request(overlay, req, NULL);
} }
static void intel_overlay_flip_prepare(struct intel_overlay *overlay,
struct i915_vma *vma)
{
enum pipe pipe = overlay->crtc->pipe;
WARN_ON(overlay->old_vma);
i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL,
vma ? vma->obj : NULL,
INTEL_FRONTBUFFER_OVERLAY(pipe));
intel_frontbuffer_flip_prepare(overlay->i915,
INTEL_FRONTBUFFER_OVERLAY(pipe));
overlay->old_vma = overlay->vma;
if (vma)
overlay->vma = i915_vma_get(vma);
else
overlay->vma = NULL;
}
/* overlay needs to be enabled in OCMD reg */ /* overlay needs to be enabled in OCMD reg */
static int intel_overlay_continue(struct intel_overlay *overlay, static int intel_overlay_continue(struct intel_overlay *overlay,
struct i915_vma *vma,
bool load_polyphase_filter) bool load_polyphase_filter)
{ {
struct drm_i915_private *dev_priv = overlay->i915; struct drm_i915_private *dev_priv = overlay->i915;
...@@ -308,43 +330,44 @@ static int intel_overlay_continue(struct intel_overlay *overlay, ...@@ -308,43 +330,44 @@ static int intel_overlay_continue(struct intel_overlay *overlay,
intel_ring_emit(ring, flip_addr); intel_ring_emit(ring, flip_addr);
intel_ring_advance(ring); intel_ring_advance(ring);
intel_overlay_flip_prepare(overlay, vma);
intel_overlay_submit_request(overlay, req, NULL); intel_overlay_submit_request(overlay, req, NULL);
return 0; return 0;
} }
static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active, static void intel_overlay_release_old_vma(struct intel_overlay *overlay)
struct drm_i915_gem_request *req)
{ {
struct intel_overlay *overlay =
container_of(active, typeof(*overlay), last_flip);
struct i915_vma *vma; struct i915_vma *vma;
vma = fetch_and_zero(&overlay->old_vma); vma = fetch_and_zero(&overlay->old_vma);
if (WARN_ON(!vma)) if (WARN_ON(!vma))
return; return;
i915_gem_track_fb(vma->obj, NULL, intel_frontbuffer_flip_complete(overlay->i915,
INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe)); INTEL_FRONTBUFFER_OVERLAY(overlay->crtc->pipe));
i915_gem_object_unpin_from_display_plane(vma); i915_gem_object_unpin_from_display_plane(vma);
i915_vma_put(vma); i915_vma_put(vma);
} }
static void intel_overlay_release_old_vid_tail(struct i915_gem_active *active,
struct drm_i915_gem_request *req)
{
struct intel_overlay *overlay =
container_of(active, typeof(*overlay), last_flip);
intel_overlay_release_old_vma(overlay);
}
static void intel_overlay_off_tail(struct i915_gem_active *active, static void intel_overlay_off_tail(struct i915_gem_active *active,
struct drm_i915_gem_request *req) struct drm_i915_gem_request *req)
{ {
struct intel_overlay *overlay = struct intel_overlay *overlay =
container_of(active, typeof(*overlay), last_flip); container_of(active, typeof(*overlay), last_flip);
struct i915_vma *vma;
/* never have the overlay hw on without showing a frame */ intel_overlay_release_old_vma(overlay);
vma = fetch_and_zero(&overlay->vma);
if (WARN_ON(!vma))
return;
i915_gem_object_unpin_from_display_plane(vma);
i915_vma_put(vma);
overlay->crtc->overlay = NULL; overlay->crtc->overlay = NULL;
overlay->crtc = NULL; overlay->crtc = NULL;
...@@ -398,6 +421,8 @@ static int intel_overlay_off(struct intel_overlay *overlay) ...@@ -398,6 +421,8 @@ static int intel_overlay_off(struct intel_overlay *overlay)
} }
intel_ring_advance(ring); intel_ring_advance(ring);
intel_overlay_flip_prepare(overlay, NULL);
return intel_overlay_do_wait_request(overlay, req, return intel_overlay_do_wait_request(overlay, req,
intel_overlay_off_tail); intel_overlay_off_tail);
} }
...@@ -836,18 +861,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, ...@@ -836,18 +861,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
intel_overlay_unmap_regs(overlay, regs); intel_overlay_unmap_regs(overlay, regs);
ret = intel_overlay_continue(overlay, scale_changed); ret = intel_overlay_continue(overlay, vma, scale_changed);
if (ret) if (ret)
goto out_unpin; goto out_unpin;
i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL,
vma->obj, INTEL_FRONTBUFFER_OVERLAY(pipe));
overlay->old_vma = overlay->vma;
overlay->vma = vma;
intel_frontbuffer_flip(dev_priv, INTEL_FRONTBUFFER_OVERLAY(pipe));
return 0; return 0;
out_unpin: out_unpin:
...@@ -1215,6 +1232,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data, ...@@ -1215,6 +1232,7 @@ int intel_overlay_put_image_ioctl(struct drm_device *dev, void *data,
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
drm_modeset_unlock_all(dev); drm_modeset_unlock_all(dev);
i915_gem_object_put(new_bo);
kfree(params); kfree(params);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment