xf86-video-intel: src/sna/sna_dri.c
Chris Wilson
ickle at kemper.freedesktop.org
Wed Oct 3 05:02:57 PDT 2012
src/sna/sna_dri.c | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
New commits:
commit 3e770f09dbe76287293fea0a8a1f231885aa1c1f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Wed Oct 3 13:00:25 2012 +0100
sna/dri: Delay the deactivation of the pageflipping
As we need to clflush the scanout buffer as we return it to the bo cache
on SNB+, it is costly to terminate the pageflipping as soon as we drop a
frame as mesa often fails to keep up to the vrefresh rate.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c
index 69c1b42..2fc3af2 100644
--- a/src/sna/sna_dri.c
+++ b/src/sna/sna_dri.c
@@ -55,6 +55,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#endif
#define COLOR_PREFER_TILING_Y 0
+#define FLIP_OFF_DELAY 5
enum frame_event_type {
DRI2_SWAP,
@@ -1431,8 +1432,22 @@ static void sna_dri_flip_event(struct sna *sna,
sna_dri_frame_event_info_free(sna, flip->draw, flip);
chain_flip(sna);
} else if (!flip->next_front.name) {
- DBG(("%s: flip chain complete\n", __FUNCTION__));
- sna_dri_frame_event_info_free(sna, flip->draw, flip);
+ /* Keep the pageflipping running for a couple of frames
+ * so we keep the uncached scanouts alive.
+ */
+ DBG(("%s: flip chain complete, off-delay=%d\n",
+ __FUNCTION__, flip->off_delay));
+ if (flip->off_delay-- && flip->draw &&
+ can_flip(sna, flip->draw, flip->front, flip->front) &&
+ (flip->count = sna_page_flip(sna,
+ get_private(flip->front)->bo,
+ flip, flip->pipe))) {
+ assert(flip == sna_dri_window_get_chain((WindowPtr)flip->draw));
+ sna->dri.flip_pending = flip;
+ } else {
+ DBG(("%s: flip chain complete, off\n", __FUNCTION__));
+ sna_dri_frame_event_info_free(sna, flip->draw, flip);
+ }
} else if (flip->draw &&
can_flip(sna, flip->draw, flip->front, flip->back)) {
sna_dri_flip_continue(sna, flip);
@@ -1445,6 +1460,7 @@ static void sna_dri_flip_event(struct sna *sna,
sna->dri.flip_pending = flip;
else
sna_dri_frame_event_info_free(sna, flip->draw, flip);
+ flip->off_delay = FLIP_OFF_DELAY;
} else {
DBG(("%s: no longer able to flip\n", __FUNCTION__));
@@ -1488,12 +1504,12 @@ static void sna_dri_flip_event(struct sna *sna,
flip->next_front.bo = get_private(flip->front)->bo;
flip->next_front.name = flip->front->name;
- flip->off_delay = 5;
+ flip->off_delay = FLIP_OFF_DELAY;
sna->dri.flip_pending = flip;
} else if (flip->draw &&
can_flip(sna, flip->draw, flip->front, flip->back) &&
- --flip->off_delay) {
+ flip->off_delay--) {
assert(flip == sna_dri_window_get_chain((WindowPtr)flip->draw));
DBG(("%s: queuing no-flip [delay=%d]\n",
__FUNCTION__, flip->off_delay));
@@ -1643,6 +1659,7 @@ sna_dri_schedule_flip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
CREATE_SCANOUT | CREATE_EXACT);
info->back->name = kgem_bo_flink(&sna->kgem,
get_private(info->back)->bo);
+ info->off_delay = FLIP_OFF_DELAY;
sna->dri.flip_pending = info;
DRI2SwapComplete(info->client, draw, 0, 0, 0,
@@ -2080,7 +2097,7 @@ blit:
info->next_front.name = info->front->name;
info->next_front.bo = get_private(info->front)->bo;
- info->off_delay = 5;
+ info->off_delay = FLIP_OFF_DELAY;
} else if (info->type != DRI2_ASYNC_FLIP) {
/* A normal vsync'ed client is finishing, wait for it
* to unpin the old framebuffer before taking over.
More information about the xorg-commit
mailing list