summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniels@collabora.com>2012-01-12 14:43:49 (GMT)
committerDaniel Stone <daniels@collabora.com>2012-01-12 14:43:49 (GMT)
commit7e5bbd748cd7bd38a686373d327ee81bc3574e51 (patch)
treebd22d4bc91f5cfc4d7464ed2ddd9091766762100
parentf237a32831824cc680c2538369bb5cc77a2b2c5e (diff)
downloadxf86-video-ti81xx-7e5bbd748cd7bd38a686373d327ee81bc3574e51.tar.gz
xf86-video-ti81xx-7e5bbd748cd7bd38a686373d327ee81bc3574e51.tar.xz
Clean up buffer_ready code
Signed-off-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--src/xv.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/src/xv.c b/src/xv.c
index 20339d8..0df4302 100644
--- a/src/xv.c
+++ b/src/xv.c
@@ -317,7 +317,7 @@ static void ti81xx_video_completion_send(struct ti81xx_video_priv *video_priv,
if (video_priv->xv_event_base == 0) {
ExtensionEntry *ext_entry = CheckExtension(XvName);
if (!ext_entry)
- FatalError("ti81xx_video_buffer_ready: Couldn't look up Xv extension\n");
+ FatalError("ti81xx_video_completion_send: Couldn't look up Xv extension\n");
video_priv->xv_event_base = ext_entry->eventBase;
}
@@ -336,19 +336,22 @@ void ti81xx_video_buffer_ready(ScrnInfoPtr xf86_screen,
struct ti81xx_screen_priv *screen_priv = get_screen_priv(xf86_screen);
struct ti81xx_video_priv *video_priv;
struct ti81xx_buffer *buf;
- int i, j, retire = 0;
- uint32_t retire_fb_id;
ClientPtr client;
+ uint32_t retire_fb_id = 0;
+ int i, j;
for (i = 0; i < screen_priv->num_video_ports; i++) {
video_priv = get_video_priv(screen_priv, i);
client = video_priv->dix_port->grab.client;
- if (client) /* XXX: only one xv client allowed?!? */
+ if (client)
break;
}
- retire_fb_id = 0;
+
+ /* We may have received a buffer ready event for one of our shadow child
+ * buffers. Find the buffer ID we should be sending to the client. */
for (j = 0; j < TI81XX_VIDEO_NUM_CLIENT_BUFFERS; j++) {
uint32_t fb_id;
+
if (screen_priv->child_buffers[j])
fb_id = screen_priv->child_buffers[j]->fb_id;
else
@@ -356,44 +359,47 @@ void ti81xx_video_buffer_ready(ScrnInfoPtr xf86_screen,
if (fb_id != event->fb_id)
continue;
+
retire_fb_id = screen_priv->client_buffers[j];
screen_priv->client_buffers[j] = 0;
if (screen_priv->child_buffers[j]) {
ti81xx_buffer_free(xf86_screen, screen_priv->child_buffers[j]);
screen_priv->child_buffers[j] = NULL;
}
+
break;
}
- if (retire_fb_id) {
- for (retire = 1, j = 0; j < TI81XX_VIDEO_NUM_CLIENT_BUFFERS; j++) {
- if (screen_priv->client_buffers[j] == retire_fb_id) {
- retire = 0;
- break;
- }
- }
- } else
- retire = 0;
-
- if (retire) {
- for (j = 0; j < TI81XX_VIDEO_NUM_BUFFERS; j++) {
- buf = video_priv->buffers.bufs[j];
- if (!buf || buf->fb_id != retire_fb_id)
- continue;
- if (buf->status != BUFFER_STATUS_QUEUED) {
- DRV_ERROR("got buffer event for non-queued buffer 0x%x\n",
- event->fb_id);
- break;
- }
- ti81xx_video_buffer_put(xf86_screen, video_priv, buf);
- return;
- }
+ if (retire_fb_id == 0)
+ return;
- if (!client)
+ /* If there are any more references to this buffer in the queue, don't send the
+ * ready event until they're all completed. */
+ for (j = 0; j < TI81XX_VIDEO_NUM_CLIENT_BUFFERS; j++) {
+ if (screen_priv->client_buffers[j] == retire_fb_id) {
return;
+ }
+ }
- ti81xx_video_completion_send(video_priv, client, retire_fb_id);
+ /* If this is an internal Xv buffer, rather than a client GEM buffer, put it
+ * back in the queue and return. */
+ for (j = 0; j < TI81XX_VIDEO_NUM_BUFFERS; j++) {
+ buf = video_priv->buffers.bufs[j];
+ if (!buf || buf->fb_id != retire_fb_id)
+ continue;
+ if (buf->status != BUFFER_STATUS_QUEUED) {
+ DRV_ERROR("got buffer event for non-queued buffer 0x%x\n",
+ event->fb_id);
+ break;
+ }
+ ti81xx_video_buffer_put(xf86_screen, video_priv, buf);
+ return;
}
+
+ if (!client)
+ return;
+
+ ti81xx_video_completion_send(video_priv, client, retire_fb_id);
}
/**