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;