xserver: Branch 'master' - 5 commits
Keith Packard
keithp at kemper.freedesktop.org
Wed Nov 20 13:13:02 PST 2013
present/present.c | 52 ++++++++++++++++++++++++++++++++++++++---------
present/present_event.c | 2 -
present/present_fake.c | 2 -
present/present_fence.c | 29 +++++++++++++++++++++++++-
present/present_priv.h | 17 +++++++++++++--
present/present_screen.c | 2 -
6 files changed, 88 insertions(+), 16 deletions(-)
New commits:
commit 6403cbb143c67872ca9c58e3116ae7942def0ae1
Author: Keith Packard <keithp at keithp.com>
Date: Tue Nov 19 22:13:54 2013 -0800
present: When unflipping, copy to flip window rather than screen
unflip happens after the clip lists have been updated, so instead of
smashing the whole screen and drawing over other windows, just draw to
the original flip window; it'll have the right clip list and so the
copy will work just fine.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
diff --git a/present/present.c b/present/present.c
index 16dc381..f9eef6b 100644
--- a/present/present.c
+++ b/present/present.c
@@ -321,8 +321,8 @@ present_unflip(ScreenPtr screen)
/* Update the screen pixmap with the current flip pixmap contents
*/
- if (screen_priv->flip_pixmap) {
- present_copy_region(&screen->GetScreenPixmap(screen)->drawable,
+ if (screen_priv->flip_pixmap && screen_priv->flip_window) {
+ present_copy_region(&screen_priv->flip_window->drawable,
screen_priv->flip_pixmap,
NULL, 0, 0);
}
commit 8bdd2ccc776ded3f527596b5009ef25129aa3287
Author: Keith Packard <keithp at keithp.com>
Date: Mon Nov 11 18:03:42 2013 -0800
present: Block for wait_fence in present_execute
Pend presentation until wait_fence is also triggered by having the
SyncFence trigger invoke present_execute once triggered.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
diff --git a/present/present.c b/present/present.c
index 67d7f6e..16dc381 100644
--- a/present/present.c
+++ b/present/present.c
@@ -453,6 +453,26 @@ present_check_flip_window (WindowPtr window)
}
/*
+ * Called when the wait fence is triggered; just gets the current msc/ust and
+ * calls present_execute again. That will re-check the fence and pend the
+ * request again if it's still not actually ready
+ */
+static void
+present_wait_fence_triggered(void *param)
+{
+ present_vblank_ptr vblank = param;
+ WindowPtr window = vblank->window;
+ uint64_t ust = 0, crtc_msc = 0;
+
+ if (window) {
+ present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
+ if (window_priv)
+ (void) present_get_ust_msc(window, window_priv->crtc, &ust, &crtc_msc);
+ }
+ present_execute(vblank, ust, crtc_msc);
+}
+
+/*
* Once the required MSC has been reached, execute the pending request.
*
* For requests to actually present something, either blt contents to
@@ -469,7 +489,10 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
present_screen_priv_ptr screen_priv = present_screen_priv(window->drawable.pScreen);
if (vblank->wait_fence) {
- /* XXX check fence, queue if not ready */
+ if (!present_fence_check_triggered(vblank->wait_fence)) {
+ present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank);
+ return;
+ }
}
xorg_list_del(&vblank->event_queue);
@@ -654,6 +677,12 @@ present_pixmap(WindowPtr window,
target_msc--;
}
+ if (wait_fence) {
+ vblank->wait_fence = present_fence_create(wait_fence);
+ if (!vblank->wait_fence)
+ goto no_mem;
+ }
+
if (idle_fence) {
vblank->idle_fence = present_fence_create(idle_fence);
if (!vblank->idle_fence)
@@ -764,6 +793,9 @@ present_vblank_destroy(present_vblank_ptr vblank)
if (vblank->update)
RegionDestroy(vblank->update);
+ if (vblank->wait_fence)
+ present_fence_destroy(vblank->wait_fence);
+
if (vblank->idle_fence)
present_fence_destroy(vblank->idle_fence);
diff --git a/present/present_event.c b/present/present_event.c
index a30bc82..a8f7176 100644
--- a/present/present_event.c
+++ b/present/present_event.c
@@ -26,8 +26,6 @@
#include "present_priv.h"
-#include "present_priv.h"
-
RESTYPE present_event_type;
static int
diff --git a/present/present_fence.c b/present/present_fence.c
index db5efca..e09657d 100644
--- a/present/present_fence.c
+++ b/present/present_fence.c
@@ -37,6 +37,8 @@
struct present_fence {
SyncTrigger trigger;
SyncFence *fence;
+ void (*callback)(void *param);
+ void *param;
};
/*
@@ -45,12 +47,18 @@ struct present_fence {
static Bool
present_fence_sync_check_trigger(SyncTrigger *trigger, XSyncValue oldval)
{
- return FALSE;
+ struct present_fence *present_fence = container_of(trigger, struct present_fence, trigger);
+
+ return present_fence->callback != NULL;
}
static void
present_fence_sync_trigger_fired(SyncTrigger *trigger)
{
+ struct present_fence *present_fence = container_of(trigger, struct present_fence, trigger);
+
+ if (present_fence->callback)
+ (*present_fence->callback)(present_fence->param);
}
static void
@@ -101,6 +109,25 @@ present_fence_set_triggered(struct present_fence *present_fence)
(*present_fence->fence->funcs.SetTriggered) (present_fence->fence);
}
+Bool
+present_fence_check_triggered(struct present_fence *present_fence)
+{
+ if (!present_fence)
+ return TRUE;
+ if (!present_fence->fence)
+ return TRUE;
+ return (*present_fence->fence->funcs.CheckTriggered)(present_fence->fence);
+}
+
+void
+present_fence_set_callback(struct present_fence *present_fence,
+ void (*callback) (void *param),
+ void *param)
+{
+ present_fence->callback = callback;
+ present_fence->param = param;
+}
+
XID
present_fence_id(struct present_fence *present_fence)
{
diff --git a/present/present_priv.h b/present/present_priv.h
index 40c88dd..500c7c2 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -249,6 +249,14 @@ present_fence_destroy(struct present_fence *present_fence);
void
present_fence_set_triggered(struct present_fence *present_fence);
+Bool
+present_fence_check_triggered(struct present_fence *present_fence);
+
+void
+present_fence_set_callback(struct present_fence *present_fence,
+ void (*callback)(void *param),
+ void *param);
+
XID
present_fence_id(struct present_fence *present_fence);
@@ -271,6 +279,13 @@ void
present_destroy_notifies(present_notify_ptr notifies, int num_notifies);
/*
+ * present_redirect.c
+ */
+
+WindowPtr
+present_redirect(ClientPtr client, WindowPtr target);
+
+/*
* present_request.c
*/
int
commit e5a188cb919edee2e3a03054276bce0db02f7b62
Author: Keith Packard <keithp at keithp.com>
Date: Sat Nov 9 12:36:47 2013 -0800
present: Signal destroyed flip window with vblank->window == NULL
This eliminates dereferencing freed window pointers when there is a
flip for that window in progress. The flip will complete, and then
immediately get undone (as we can't stop an in-progress flip).
Remove the vblank->window_destroyed field as we can signal this with
vblank->window == NULL instead.
Change check to vblank->window == NULL in:
present_flip_notify
Add check for vblank->window == NULL in:
present_vblank_notify
present_execute
present_flip_notify was also using vblank->window->drawable.pScreen,
so stop doing that and use vblank->screen instead.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
diff --git a/present/present.c b/present/present.c
index bfafa92..67d7f6e 100644
--- a/present/present.c
+++ b/present/present.c
@@ -171,7 +171,8 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_
{
int n;
- present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset);
+ if (vblank->window)
+ present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset);
for (n = 0; n < vblank->num_notifies; n++) {
WindowPtr window = vblank->notifies[n].window;
CARD32 serial = vblank->notifies[n].serial;
@@ -336,8 +337,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
static void
present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
{
- WindowPtr window = vblank->window;
- ScreenPtr screen = window->drawable.pScreen;
+ ScreenPtr screen = vblank->screen;
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
DebugPresent(("\tn %p %8lld: %08lx -> %08lx\n", vblank, vblank->target_msc,
@@ -363,8 +363,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
if (vblank->abort_flip)
present_unflip(screen);
- if (!vblank->window_destroyed)
- present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
+ present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
present_vblank_destroy(vblank);
}
@@ -474,7 +473,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
}
xorg_list_del(&vblank->event_queue);
- if (vblank->pixmap) {
+ if (vblank->pixmap && vblank->window) {
if (vblank->flip && screen_priv->flip_pending == NULL && !screen_priv->unflip_event_id) {
diff --git a/present/present_priv.h b/present/present_priv.h
index a92b62a..40c88dd 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -72,8 +72,6 @@ struct present_vblank {
Bool flip;
Bool sync_flip;
Bool abort_flip;
-
- Bool window_destroyed;
};
typedef struct present_screen_priv {
diff --git a/present/present_screen.c b/present/present_screen.c
index 50b2b2d..2702cd6 100644
--- a/present/present_screen.c
+++ b/present/present_screen.c
@@ -92,7 +92,7 @@ present_clear_window_flip(WindowPtr window)
if (flip_pending && flip_pending->window == window) {
assert (flip_pending->abort_flip);
- flip_pending->window_destroyed = TRUE;
+ flip_pending->window = NULL;
}
if (screen_priv->flip_window == window)
screen_priv->flip_window = NULL;
commit a5bcc4f7b9499caf8993f0a6ef96088553399ca3
Author: Keith Packard <keithp at keithp.com>
Date: Sat Nov 9 12:33:02 2013 -0800
present: Ignore event_id 0 from driver vblank notify
We use event_id 0 to mean 'no such event'; if a driver sends us that
event_id, make sure we don't accidentally match it.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
diff --git a/present/present.c b/present/present.c
index 228d43a..bfafa92 100644
--- a/present/present.c
+++ b/present/present.c
@@ -374,6 +374,8 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
present_vblank_ptr vblank, tmp;
int s;
+ if (!event_id)
+ return;
DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc));
xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
if (vblank->event_id == event_id) {
@@ -398,6 +400,7 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
DebugPresent(("\tun %lld\n", event_id));
screen_priv->unflip_event_id = 0;
present_flip_idle(screen);
+ return;
}
}
}
commit 4f3c37a1f17ffcfbbff71d217e1caad3d0148c90
Author: Keith Packard <keithp at keithp.com>
Date: Thu Nov 7 14:17:12 2013 -0800
present: Round fake MSC computations intead of truncating
If the timer fired too early, we'd sometimes mis-compute the MSC for
fake vblanks. Rounding the computation to the nearest MSC fixes this nicely.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Adam Jackson <ajax at redhat.com>
diff --git a/present/present_fake.c b/present/present_fake.c
index a677592..e550e98 100644
--- a/present/present_fake.c
+++ b/present/present_fake.c
@@ -42,7 +42,7 @@ present_fake_get_ust_msc(ScreenPtr screen, uint64_t *ust, uint64_t *msc)
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
*ust = GetTimeInMicros();
- *msc = *ust / screen_priv->fake_interval;
+ *msc = (*ust + screen_priv->fake_interval / 2) / screen_priv->fake_interval;
return Success;
}
More information about the xorg-commit
mailing list