xf86-video-intel: 2 commits - src/sna/sna_dri2.c

Chris Wilson ickle at kemper.freedesktop.org
Fri May 23 06:02:45 PDT 2014


 src/sna/sna_dri2.c |  137 ++++++++++++++++++++++-------------------------------
 1 file changed, 59 insertions(+), 78 deletions(-)

New commits:
commit 605fcd9050efc816ac8163e8d626f466d98261c2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 23 13:34:38 2014 +0100

    sna/dri2: Handle allocation failure adding frame events gracefully
    
    Now that we do not preallocate the storage for the chain in the Window
    devPrivates, we need to check for an allocation failure.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 8589ffe..4b1775d 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -474,9 +474,10 @@ static void sna_dri2_destroy_buffer(DrawablePtr draw, DRI2Buffer2Ptr buffer)
 	_sna_dri2_destroy_buffer(to_sna_from_drawable(draw), buffer);
 }
 
-static void sna_dri2_reference_buffer(DRI2BufferPtr buffer)
+static DRI2BufferPtr sna_dri2_reference_buffer(DRI2BufferPtr buffer)
 {
 	get_private(buffer)->refcnt++;
+	return buffer;
 }
 
 static inline void damage(PixmapPtr pixmap, struct sna_pixmap *priv, RegionPtr region)
@@ -943,12 +944,12 @@ struct dri2_window {
 
 static struct dri2_window *dri2_window(WindowPtr win)
 {
-	assert(win->drawable.type == DRAWABLE_WINDOW);
 	return ((void **)__get_private(win, sna_window_key))[1];
 }
 
 static void dri2_window_attach(WindowPtr win, struct dri2_window *priv)
 {
+	assert(win->drawable.type == DRAWABLE_WINDOW);
 	assert(dri2_window(win) == NULL);
 	((void **)__get_private(win, sna_window_key))[1] = priv;
 	assert(dri2_window(win) == priv);
@@ -1053,25 +1054,35 @@ sna_dri2_remove_frame_event(WindowPtr win,
 	chain->chain = info->chain;
 }
 
-static void
-sna_dri2_add_frame_event(DrawablePtr draw, struct sna_dri2_frame_event *info)
+static struct sna_dri2_frame_event *
+sna_dri2_add_frame_event(DrawablePtr draw, ClientPtr client)
 {
 	struct dri2_window *priv;
-	struct sna_dri2_frame_event *chain;
-
-	if (draw->type != DRAWABLE_WINDOW)
-		return;
+	struct sna_dri2_frame_event *info, *chain;
 
+	assert(draw->type == DRAWABLE_WINDOW);
 	DBG(("%s: add[%p] to window %ld)\n",
 	     __FUNCTION__, info, (long)draw->id));
 
 	priv = dri2_window((WindowPtr)draw);
-	assert(priv);
+	if (priv == NULL)
+		return NULL;
+
+	info = calloc(1, sizeof(struct sna_dri2_frame_event));
+	if (info == NULL)
+		return NULL;
+
+	list_init(&info->cache);
+	info->draw = draw;
+	info->client = client;
+	info->crtc = priv->crtc;
+	info->pipe = sna_crtc_to_pipe(priv->crtc);
+
 	assert(priv->chain != info);
 
 	if (priv->chain == NULL) {
 		priv->chain = info;
-		return;
+		return info;
 	}
 
 	chain = priv->chain;
@@ -1080,6 +1091,7 @@ sna_dri2_add_frame_event(DrawablePtr draw, struct sna_dri2_frame_event *info)
 
 	assert(chain != info);
 	chain->chain = info;
+	return info;
 }
 
 static void
@@ -1121,15 +1133,16 @@ sna_dri2_frame_event_info_free(struct sna *sna,
 
 void sna_dri2_destroy_window(WindowPtr win)
 {
-	struct sna *sna = to_sna_from_drawable(&win->drawable);
-	struct dri2_window *priv = dri2_window(win);
+	struct dri2_window *priv;
 
+	priv = dri2_window(win);
 	if (priv == NULL)
 		return;
 
 	DBG(("%s: window=%ld\n", __FUNCTION__, win->drawable.serialNumber));
 
 	if (priv->chain) {
+		struct sna *sna = to_sna_from_drawable(&win->drawable);
 		struct sna_dri2_frame_event *info, *chain;
 
 		DBG(("%s: freeing chain\n", __FUNCTION__));
@@ -2028,7 +2041,6 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 {
 	struct sna *sna = to_sna_from_drawable(draw);
 	struct sna_dri2_frame_event *info;
-	int pipe = sna_crtc_to_pipe(crtc);
 	uint64_t current_msc;
 
 	if (immediate_swap(sna, *target_msc, divisor, draw, crtc, &current_msc)) {
@@ -2036,15 +2048,14 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 
 		info = sna->dri2.flip_pending;
 		DBG(("%s: performing immediate swap on pipe %d, pending? %d, mode: %d\n",
-		     __FUNCTION__, pipe, info != NULL, info ? info->mode : 0));
+		     __FUNCTION__, sna_crtc_to_pipe(crtc), info != NULL, info ? info->mode : 0));
 
 		if (info && info->draw == draw) {
 			assert(info->type != FLIP);
 			assert(info->front == front);
 			if (info->back != back) {
 				_sna_dri2_destroy_buffer(sna, info->back);
-				info->back = back;
-				sna_dri2_reference_buffer(back);
+				info->back = sna_dri2_reference_buffer(back);
 			}
 			if (current_msc >= *target_msc) {
 				DBG(("%s: executing xchg of pending flip\n",
@@ -2061,28 +2072,21 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
 			}
 		}
 
-		info = calloc(1, sizeof(struct sna_dri2_frame_event));
+		info = sna_dri2_add_frame_event(draw, client);
 		if (info == NULL)
 			return false;
 
-		list_init(&info->cache);
-		info->draw = draw;
-		info->client = client;
+		assert(info->crtc == crtc);
 		info->event_complete = func;
 		info->event_data = data;
-		info->front = front;
-		info->back = back;
-		info->crtc = crtc;
-		info->pipe = pipe;
+
+		info->front = sna_dri2_reference_buffer(front);
+		info->back = sna_dri2_reference_buffer(back);
 
 		info->scanout[0].bo = ref(get_private(front)->bo);
 		info->scanout[0].name = info->front->name;
 		assert(info->scanout[0].bo->scanout);
 
-		sna_dri2_add_frame_event(draw, info);
-		sna_dri2_reference_buffer(front);
-		sna_dri2_reference_buffer(back);
-
 		if (sna->dri2.flip_pending) {
 			/* We need to first wait (one vblank) for the
 			 * async flips to complete before this client
@@ -2115,29 +2119,22 @@ out:
 		return true;
 	}
 
-	info = calloc(1, sizeof(struct sna_dri2_frame_event));
+	info = sna_dri2_add_frame_event(draw, client);
 	if (info == NULL)
 		return false;
 
-	list_init(&info->cache);
-	info->draw = draw;
-	info->client = client;
+	assert(info->crtc == crtc);
 	info->event_complete = func;
 	info->event_data = data;
-	info->front = front;
-	info->back = back;
-	info->crtc = crtc;
-	info->pipe = pipe;
 	info->type = FLIP;
 
+	info->front = sna_dri2_reference_buffer(front);
+	info->back = sna_dri2_reference_buffer(back);
+
 	info->scanout[0].bo = ref(get_private(front)->bo);
 	info->scanout[0].name = info->front->name;
 	assert(info->scanout[0].bo->scanout);
 
-	sna_dri2_add_frame_event(draw, info);
-	sna_dri2_reference_buffer(front);
-	sna_dri2_reference_buffer(back);
-
 	/*
 	 * If divisor is zero, or current_msc is smaller than target_msc
 	 * we just need to make sure target_msc passes before initiating
@@ -2175,7 +2172,7 @@ out:
 		vbl.reply.sequence = draw_target_seq(draw, *target_msc - 1);
 		vbl.request.signal = (unsigned long)info;
 
-		if (sna_wait_vblank(sna, &vbl, pipe)) {
+		if (sna_wait_vblank(sna, &vbl, info->pipe)) {
 			sna_dri2_frame_event_info_free(sna, draw, info);
 			return false;
 		}
@@ -2266,23 +2263,16 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 
 	VG_CLEAR(vbl);
 
-	info = calloc(1, sizeof(struct sna_dri2_frame_event));
+	info = sna_dri2_add_frame_event(draw, client);
 	if (!info)
 		goto blit;
 
-	list_init(&info->cache);
-	info->draw = draw;
-	info->client = client;
+	assert(info->crtc == crtc);
 	info->event_complete = func;
 	info->event_data = data;
-	info->front = front;
-	info->back = back;
-	info->crtc = crtc;
-	info->pipe = sna_crtc_to_pipe(crtc);
 
-	sna_dri2_add_frame_event(draw, info);
-	sna_dri2_reference_buffer(front);
-	sna_dri2_reference_buffer(back);
+	info->front = sna_dri2_reference_buffer(front);
+	info->back = sna_dri2_reference_buffer(back);
 
 	info->type = SWAP;
 
@@ -2446,17 +2436,12 @@ sna_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc
 	if (divisor == 0 && current_msc >= target_msc)
 		goto out_complete;
 
-	info = calloc(1, sizeof(struct sna_dri2_frame_event));
+	info = sna_dri2_add_frame_event(draw, client);
 	if (!info)
 		goto out_complete;
 
-	list_init(&info->cache);
-	info->draw = draw;
-	info->client = client;
+	assert(info->crtc == crtc);
 	info->type = WAITMSC;
-	info->crtc = crtc;
-	info->pipe = pipe;
-	sna_dri2_add_frame_event(draw, info);
 
 	vbl.request.signal = (unsigned long)info;
 	vbl.request.type = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
commit 36a4a654da87b22f7ce31d1ca99389cedb57eee8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 23 12:48:10 2014 +0100

    sna/dri2: Tidy add/remove chain to use the common DRI2 private
    
    The code is more readable directly updating the private rather than
    hiding the pointer chasing through the opaque lookups.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 7f2b056..8589ffe 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -1026,34 +1026,26 @@ sna_dri2_window_get_chain(WindowPtr win)
 }
 
 static void
-sna_dri2_window_set_chain(WindowPtr win,
-			  struct sna_dri2_frame_event *chain)
-{
-	struct dri2_window *priv = dri2_window(win);
-	DBG(("%s: head now %p\n", __FUNCTION__, chain));
-	assert(priv != NULL);
-	assert(sna_dri2_window_get_chain(win) != chain);
-	priv->chain = chain;
-}
-
-static void
 sna_dri2_remove_frame_event(WindowPtr win,
 			    struct sna_dri2_frame_event *info)
 {
+	struct dri2_window *priv;
 	struct sna_dri2_frame_event *chain;
 
+	assert(win->drawable.type == DRAWABLE_WINDOW);
 	DBG(("%s: remove[%p] from window %ld)\n",
 	     __FUNCTION__, info, (long)win->drawable.id));
 
-	chain = sna_dri2_window_get_chain(win);
-	if (chain == NULL)
-		return;
+	priv = dri2_window(win);
+	assert(priv);
+	assert(priv->chain != NULL);
 
-	if (chain == info) {
-		sna_dri2_window_set_chain(win, info->chain);
+	if (priv->chain == info) {
+		priv->chain = info->chain;
 		return;
 	}
 
+	chain = priv->chain;
 	while (chain->chain != info)
 		chain = chain->chain;
 	assert(chain != info);
@@ -1064,6 +1056,7 @@ sna_dri2_remove_frame_event(WindowPtr win,
 static void
 sna_dri2_add_frame_event(DrawablePtr draw, struct sna_dri2_frame_event *info)
 {
+	struct dri2_window *priv;
 	struct sna_dri2_frame_event *chain;
 
 	if (draw->type != DRAWABLE_WINDOW)
@@ -1072,13 +1065,16 @@ sna_dri2_add_frame_event(DrawablePtr draw, struct sna_dri2_frame_event *info)
 	DBG(("%s: add[%p] to window %ld)\n",
 	     __FUNCTION__, info, (long)draw->id));
 
-	chain = sna_dri2_window_get_chain((WindowPtr)draw);
-	if (chain == NULL) {
-		sna_dri2_window_set_chain((WindowPtr)draw, info);
+	priv = dri2_window((WindowPtr)draw);
+	assert(priv);
+	assert(priv->chain != info);
+
+	if (priv->chain == NULL) {
+		priv->chain = info;
 		return;
 	}
 
-	assert(chain != info);
+	chain = priv->chain;
 	while (chain->chain != NULL)
 		chain = chain->chain;
 


More information about the xorg-commit mailing list