weston: modify buffer release flow [1/1]

PD#SWPL-128839

Problem:
there is only one buffer release queue.
some video buffer is not released when there are two video playing.

Solution:
modify buffer release queue and every video surface has its own
buffer release queue.

Verify:
ah212

Change-Id: I9862e20c958611f2ef420692084f9e1786bf865f
Signed-off-by: limin.tian <limin.tian@amlogic.com>
diff --git a/aml-weston/aml-compositor.c b/aml-weston/aml-compositor.c
index 8daf83e..0195931 100644
--- a/aml-weston/aml-compositor.c
+++ b/aml-weston/aml-compositor.c
@@ -47,15 +47,8 @@
 #define DMA_BUF_IOCTL_EXPORT_SYNC_FILE	_IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file)
 #endif
 
-#define FRAMES_RELEASE (3)
-#define FRAME_CURR (0)
-#define FRAME_PREV (1)
-#define FRAME_FREE (2)
-#define MAX_VIDEO_SURFACE 2
 
-static struct weston_buffer* video_buffer_release[FRAMES_RELEASE];
-static bool release_cur = false;
-static bool release_pre = false;
+#define MAX_VIDEO_SURFACE 2
 
 #ifdef ENABLE_DRM_HELP
 static void weston_compositor_print_node_info(struct weston_compositor *ec);
@@ -111,11 +104,9 @@
 static void weston_clear_video_surface_info(struct weston_surface *surface)
 {
 	if (surface->is_video_surface) {
-		video_buffer_release[FRAME_FREE] = NULL;
-		video_buffer_release[FRAME_PREV] = NULL;
-		video_buffer_release[FRAME_CURR] = NULL;
-		release_cur = false;
-		release_pre = false;
+		surface->video_buffer_release[FRAME_FREE] = NULL;
+		surface->video_buffer_release[FRAME_PREV] = NULL;
+		surface->video_buffer_release[FRAME_CURR] = NULL;
 		if (surface->compositor->video_surface_count > 0)
 			surface->compositor->video_surface_count -= 1;
 	}
@@ -219,77 +210,66 @@
 	return isVideoBuffer;
 }
 
-WL_EXPORT void weston_release_stranded_buffers()
+WL_EXPORT void weston_release_stranded_buffers(struct weston_compositor *compositor)
 {
-	struct timespec time;
-	if (video_buffer_release[FRAME_FREE] != NULL) {
-		weston_compositor_get_time(&time);
-		weston_log("\n weston_release_stranded_buffers  line:%d :%p, time:%lld \n", __LINE__,
-				video_buffer_release[FRAME_FREE], timespec_to_usec(&time));
-		wl_buffer_send_release(video_buffer_release[FRAME_FREE]->resource);
-		video_buffer_release[FRAME_FREE] = NULL;
+	struct weston_view* view = NULL;
+	int i = -1;
+	wl_list_for_each(view, &compositor->view_list, link) {
+		if (view && view->surface && view->surface->is_video_surface) {
+			for (i = FRAMES_RELEASE -1; i >= 0; i--  ) {
+				if (view->surface->video_buffer_release[i]
+					&& view->surface->video_buffer_release[i]->attach > 0) {
+					wl_buffer_send_release(view->surface->video_buffer_release[i]->resource);
+					view->surface->video_buffer_release[i]->attach =
+						view->surface->video_buffer_release[i]->attach -1;
+					view->surface->video_buffer_release[i] = NULL;
+				}
+			}
+		} else {
+			continue;
+		}
 	}
-	if (video_buffer_release[FRAME_PREV] != NULL) {
-		weston_compositor_get_time(&time);
-		weston_log("\n weston_release_stranded_buffers  line:%d :%p, time:%lld \n", __LINE__,
-				video_buffer_release[FRAME_PREV], timespec_to_usec(&time));
-		wl_buffer_send_release(video_buffer_release[FRAME_PREV]->resource);
-		video_buffer_release[FRAME_PREV] = NULL;
-	}
-	if (video_buffer_release[FRAME_CURR] != NULL) {
-		weston_compositor_get_time(&time);
-		weston_log("\n weston_release_stranded_buffers  line:%d :%p, time:%lld \n", __LINE__,
-				video_buffer_release[FRAME_CURR], timespec_to_usec(&time));
-		wl_buffer_send_release(video_buffer_release[FRAME_CURR]->resource);
-		video_buffer_release[FRAME_CURR] = NULL;
-	}
-	release_cur = false;
-	release_pre = false;
 }
 
 static void buffer_send_release(struct weston_buffer_reference *ref)
 {
+
 	if (!is_video_buffer(ref->buffer)) {
 		wl_buffer_send_release(ref->buffer->resource);
+		ref->buffer->attach = ref->buffer->attach -1;
 	} else {
 		int fence_rc = -1;
-		video_buffer_release[FRAME_FREE] = video_buffer_release[FRAME_PREV];
-		video_buffer_release[FRAME_PREV] = video_buffer_release[FRAME_CURR];
-		video_buffer_release[FRAME_CURR] = ref->buffer;
-		if (video_buffer_release[FRAME_FREE] != NULL && release_pre == false ) {
-			//no matter get fence or not,send release anyway
-			wl_buffer_send_release(video_buffer_release[FRAME_FREE]->resource);
-			video_buffer_release[FRAME_FREE] = NULL;
-		}
-		if (video_buffer_release[FRAME_PREV] != NULL && release_cur == true) {
-			release_pre = true;
-		}
-		if (video_buffer_release[FRAME_PREV] != NULL && release_cur == false) {
-			fence_rc = video_fence(video_buffer_release[FRAME_PREV]);
-			if (fence_rc == 1) {
-				wl_buffer_send_release(video_buffer_release[FRAME_PREV]->resource);
-				video_buffer_release[FRAME_PREV] = NULL;
-				release_pre = true;
-			} else {
-				release_pre = false;
+		int i = -1;
+		ref->buffer->surface->video_buffer_release[FRAME_FREE] = ref->buffer->surface->video_buffer_release[FRAME_PREV];
+		ref->buffer->surface->video_buffer_release[FRAME_PREV] = ref->buffer->surface->video_buffer_release[FRAME_CURR];
+		ref->buffer->surface->video_buffer_release[FRAME_CURR] = ref->buffer;
+
+		for (i = FRAME_FREE; i >= 0; i--  ) {
+			if (ref->buffer->surface->video_buffer_release[i]
+				&& ( ref->buffer->surface->video_buffer_release[i]->attach > 0) ) {
+
+				fence_rc = -1;
+				if (i != FRAME_FREE )
+					fence_rc = video_fence(ref->buffer->surface->video_buffer_release[i]);
+				else
+					fence_rc = 1;
+				if (fence_rc == 1) {
+					wl_buffer_send_release(ref->buffer->surface->video_buffer_release[i]->resource);
+					ref->buffer->surface->video_buffer_release[i]->attach =
+						ref->buffer->surface->video_buffer_release[i]->attach -1;
+					ref->buffer->surface->video_buffer_release[i] = NULL;
+				}
 			}
 		}
-		if (video_buffer_release[FRAME_CURR] != NULL) {
-			fence_rc = -1;
-			fence_rc = video_fence(video_buffer_release[FRAME_CURR]);
-			if (fence_rc == 1) {
-				wl_buffer_send_release(video_buffer_release[FRAME_CURR]->resource);
-				video_buffer_release[FRAME_CURR] = NULL;
-				release_cur = true;
-			} else {
-				release_cur = false;
-			}
-		}
-		if (!release_cur && video_buffer_release[FRAME_CURR]->commit_fail) {
-			wl_buffer_send_release(video_buffer_release[FRAME_CURR]->resource);
-			video_buffer_release[FRAME_CURR]->commit_fail = false;
-			video_buffer_release[FRAME_CURR] = NULL;
-			release_cur = true;
+		if (ref->buffer->surface->video_buffer_release[FRAME_CURR] &&
+			ref->buffer->surface->video_buffer_release[FRAME_CURR]->commit_fail &&
+			(ref->buffer->surface->video_buffer_release[FRAME_CURR]->attach > 0) ) {
+			weston_log("\n %s %d buffer:%p\n", __FUNCTION__,__LINE__, ref->buffer->surface->video_buffer_release[FRAME_CURR]);
+			wl_buffer_send_release(ref->buffer->surface->video_buffer_release[FRAME_CURR]->resource);
+			ref->buffer->surface->video_buffer_release[FRAME_CURR]->attach =
+					ref->buffer->surface->video_buffer_release[FRAME_CURR]->attach -1;
+			ref->buffer->surface->video_buffer_release[FRAME_CURR]->commit_fail = false;
+			ref->buffer->surface->video_buffer_release[FRAME_CURR] = NULL;
 		}
 	}
 }
@@ -316,9 +296,9 @@
 					}
 					if (dmabuf->direct_display) {
 						if (surface->is_video_surface == false) {
-							video_buffer_release[FRAME_CURR] = NULL;
-							video_buffer_release[FRAME_PREV] = NULL;
-							video_buffer_release[FRAME_FREE] = NULL;
+							surface->video_buffer_release[FRAME_CURR] = NULL;
+							surface->video_buffer_release[FRAME_PREV] = NULL;
+							surface->video_buffer_release[FRAME_FREE] = NULL;
 							surface->is_video_surface = true;
 						}
 					}
diff --git a/aml-weston/aml-main.c b/aml-weston/aml-main.c
index 4da40c1..0d0b6c2 100644
--- a/aml-weston/aml-main.c
+++ b/aml-weston/aml-main.c
@@ -59,13 +59,13 @@
 	if (((connected || forced) && should_enable) && !enabled) {
 		if (strcmp("HDMI-A-1", head->name) == 0) {
 			weston_log("\n enable HDMI  and release stranded buffers\n");
-			weston_release_stranded_buffers();
+			weston_release_stranded_buffers(wet->compositor);
 		}
 		drm_head_prepare_enable(wet, head);
 	} else if (!((connected || forced) && should_enable) && enabled) {
 		if (strcmp("HDMI-A-1", head->name) == 0) {
 			weston_log("\n disable HDMI and release stranded buffers\n");
-			weston_release_stranded_buffers();
+			weston_release_stranded_buffers(wet->compositor);
 		}
 		drm_head_disable(head);
 	} else if (enabled && changed) {
@@ -166,7 +166,7 @@
 
 		if (strcmp(name, "HDMI-A-1") == 0 && !(connected || forced) && enabled) {
 			drm_head_disable(head);
-			weston_release_stranded_buffers();
+			weston_release_stranded_buffers(compositor);
 			continue;
 		}
 
diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h
index 8b0c24b..2b252ce 100644
--- a/include/libweston/libweston.h
+++ b/include/libweston/libweston.h
@@ -46,6 +46,10 @@
 #define MESON_VIDEO_PLAN_SUPPORT 1
 #define SURFACE_QUEUE_CAPACITY 10
 #define INIT_VALUE 255
+#define FRAMES_RELEASE (3)
+#define FRAME_CURR (0)
+#define FRAME_PREV (1)
+#define FRAME_FREE (2)
 
 struct weston_geometry {
 	int32_t x, y;
@@ -1224,6 +1228,8 @@
 	void *backend_private;
 	uint64_t pts;
 	bool commit_fail;
+	struct weston_surface *surface;
+	int attach;
 };
 
 struct weston_buffer_reference {
@@ -1608,6 +1614,7 @@
 	struct weston_plane* plane;
 	struct wl_resource *destroy_cb;
 	int invisible;
+	struct weston_buffer* video_buffer_release[FRAMES_RELEASE];
 };
 
 struct weston_subsurface {
@@ -1823,7 +1830,7 @@
 weston_surface_create(struct weston_compositor *compositor);
 
 void
-weston_release_stranded_buffers();
+weston_release_stranded_buffers(struct weston_compositor *compositor);
 
 void
 weston_view_opacity(struct weston_view *view, float opacity);
diff --git a/libweston/compositor.c b/libweston/compositor.c
index c8a2a6c..94af173 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -3491,7 +3491,9 @@
 	/* Attach, attach, without commit in between does not send
 	 * wl_buffer.release. */
 	weston_surface_state_set_buffer(&surface->pending, buffer);
+	buffer->surface = surface;
 
+	buffer->attach = buffer->attach+1;
 	surface->pending.sx = sx;
 	surface->pending.sy = sy;
 	surface->pending.newly_attached = 1;