[Libva] [Driver PATCH 4/5] support vaGetSurfaceBufferWl
Zhao Halley
halley.zhao at intel.com
Tue Jun 5 02:12:11 PDT 2012
From: Zhao halley <halley.zhao at intel.com>
---
src/i965_drv_video.c | 5 +
src/i965_render_wayland.c | 313 ++++++++++++++++-----------------------------
src/i965_render_wayland.h | 2 +
3 files changed, 117 insertions(+), 203 deletions(-)
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 79f96f3..daa972e 100755
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -3206,6 +3206,11 @@ i965_Terminate(VADriverContextP ctx)
if (i965_post_processing_terminate(ctx) == False)
return VA_STATUS_ERROR_UNKNOWN;
+#if USE_WAYLAND
+ if (i965_render_wayland_terminate(ctx) == False)
+ return VA_STATUS_ERROR_UNKNOWN;
+#endif
+
if (intel_driver_terminate(ctx) == False)
return VA_STATUS_ERROR_UNKNOWN;
diff --git a/src/i965_render_wayland.c b/src/i965_render_wayland.c
index 26d7ba0..7d09a77 100755
--- a/src/i965_render_wayland.c
+++ b/src/i965_render_wayland.c
@@ -35,162 +35,23 @@
#define VA_WL_FORMAT_RGBA (WL_DRM_FORMAT_XRGB8888)
-struct va_wl_surface {
- struct wl_drm *wl_drm;
- struct wl_surface *wl_surface;
- struct wl_buffer *wl_buffer;
- struct intel_region region;
- unsigned int name;
- unsigned int format;
- unsigned int width;
- unsigned int height;
-};
-
-static void
-va_surface_reset_buffer(
+static bool
+i965_draw_region_reset(
VADriverContextP ctx,
- struct va_wl_surface *va_wl_surface
+ struct object_surface *obj_surface
)
{
- struct intel_region * const region = &va_wl_surface->region;
-
- if (va_wl_surface->wl_buffer) {
-#if 0
- /* XXX: automatically destroyed on next wl_surface_attach()? */
- wl_buffer_destroy(va_wl_surface->wl_buffer);
-#endif
- va_wl_surface->wl_buffer = NULL;
- }
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ struct i965_render_state * const render_state = &i965->render_state;
+ struct intel_region *region = render_state->draw_region;
+ struct VADriverVTableWayland * const vtable = ctx->vtable_wayland;
if (region->bo) {
dri_bo_unreference(region->bo);
region->bo = NULL;
}
- va_wl_surface->name = 0;
- va_wl_surface->format = 0;
- va_wl_surface->width = 0;
- va_wl_surface->height = 0;
memset(region, 0, sizeof(*region));
-}
-
-static VAStatus
-va_wayland_create_surface(
- VADriverContextP ctx,
- struct wl_surface *wl_surface,
- struct va_wl_surface **out_va_wl_surface
-)
-{
- struct va_wl_surface *va_wl_surface;
- uint32_t id;
-
- if (ctx->display_type != VA_DISPLAY_WAYLAND)
- return VA_STATUS_ERROR_INVALID_DISPLAY;
- if (!wl_surface)
- return VA_STATUS_ERROR_INVALID_SURFACE;
- if (!out_va_wl_surface)
- return VA_STATUS_ERROR_INVALID_PARAMETER;
-
- va_wl_surface = calloc(1, sizeof(*va_wl_surface));
- if (!va_wl_surface)
- return VA_STATUS_ERROR_ALLOCATION_FAILED;
-
- id = wl_display_get_global(ctx->native_dpy, "wl_drm", 1);
- if (!id) {
- wl_display_roundtrip(ctx->native_dpy);
- id = wl_display_get_global(ctx->native_dpy, "wl_drm", 1);
- if (!id)
- return VA_STATUS_ERROR_INVALID_DISPLAY;
- }
-
- va_wl_surface->wl_drm =
- wl_display_bind(ctx->native_dpy, id, &wl_drm_interface);
- if (!va_wl_surface->wl_drm)
- return VA_STATUS_ERROR_INVALID_DISPLAY;
-
- va_wl_surface->wl_surface = wl_surface;
- va_wl_surface->wl_buffer = NULL;
- va_wl_surface->format = 0;
- va_wl_surface->width = 0;
- va_wl_surface->height = 0;
-
- *out_va_wl_surface = va_wl_surface;
- return VA_STATUS_SUCCESS;
-}
-
-static VAStatus
-va_wayland_destroy_surface(
- VADriverContextP ctx,
- struct va_wl_surface *va_wl_surface
-)
-{
- if (ctx->display_type != VA_DISPLAY_WAYLAND)
- return VA_STATUS_ERROR_INVALID_DISPLAY;
- if (!va_wl_surface)
- return VA_STATUS_ERROR_INVALID_SURFACE;
-
- va_surface_reset_buffer(ctx, va_wl_surface);
-
- if (va_wl_surface->wl_drm) {
- wl_drm_destroy(va_wl_surface->wl_drm);
- va_wl_surface->wl_drm = NULL;
- }
-
- free(va_wl_surface);
- return VA_STATUS_SUCCESS;
-}
-
-static VAStatus
-va_surface_relink_buffer(
- VADriverContextP ctx,
- struct va_wl_surface *va_wl_surface
-)
-{
- struct i965_driver_data * const i965 = i965_driver_data(ctx);
- struct i965_render_state * const render_state = &i965->render_state;
- struct intel_region *region = render_state->draw_region;
- uint32_t name;
-
- if (region) {
- if (!region->bo || dri_bo_flink(region->bo, &name) != 0)
- return VA_STATUS_ERROR_INVALID_BUFFER;
-
- if (name != va_wl_surface->name) {
- dri_bo_unreference(region->bo);
- region->bo = NULL;
- }
- }
- else {
- region = calloc(1, sizeof(*region));
- if (!region)
- return VA_STATUS_ERROR_ALLOCATION_FAILED;
- render_state->draw_region = region;
- }
-
- if (!region->bo) {
- *region = va_wl_surface->region;
-
- region->bo = intel_bo_gem_create_from_name(
- i965->intel.bufmgr,
- "render buffer",
- va_wl_surface->name
- );
- assert(region->bo);
- if (!region->bo)
- return VA_STATUS_ERROR_ALLOCATION_FAILED;
- }
- return VA_STATUS_SUCCESS;
-}
-
-static bool
-va_surface_create_buffer_rgb(
- VADriverContextP ctx,
- struct va_wl_surface *va_wl_surface,
- struct object_surface *obj_surface
-)
-{
- struct i965_driver_data * const i965 = i965_driver_data(ctx);
- struct intel_region * const region = &va_wl_surface->region;
region->x = 0;
region->y = 0;
@@ -209,45 +70,46 @@ va_surface_create_buffer_rgb(
return false;
dri_bo_get_tiling(region->bo, ®ion->tiling, ®ion->swizzle);
- if (dri_bo_flink(region->bo, &va_wl_surface->name) != 0) {
+
+ if (dri_bo_flink(region->bo, &vtable->name) != 0) {
fprintf(stderr, "libva: error: flink failed for bo %p\n", region->bo);
return false;
}
-
- va_wl_surface->format = VA_WL_FORMAT_RGBA;
- va_wl_surface->width = obj_surface->orig_width;
- va_wl_surface->height = obj_surface->orig_height;
+
return true;
}
static VAStatus
-va_attach_rgb_surface(
+i965_render_surface_rgb(
VADriverContextP ctx,
- struct va_wl_surface *va_wl_surface,
struct object_surface *obj_surface,
unsigned int flags
)
{
- struct intel_region * const region = &va_wl_surface->region;
VAStatus va_status;
VASurfaceID va_surface;
VARectangle src_rect, dst_rect;
unsigned int pp_flags;
+
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ struct i965_render_state * const render_state = &i965->render_state;
+ struct intel_region *region = render_state->draw_region;
+
+ if (!region) {
+ region = calloc(1, sizeof(*region));
+ if (!region)
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ render_state->draw_region = region;
+ }
/* Check local buffer */
- if (va_wl_surface->format != VA_WL_FORMAT_RGBA ||
- va_wl_surface->width != obj_surface->orig_width ||
- va_wl_surface->height != obj_surface->orig_height) {
- va_surface_reset_buffer(ctx, va_wl_surface);
- if (!va_surface_create_buffer_rgb(ctx, va_wl_surface, obj_surface))
+ if (region->width != obj_surface->orig_width ||
+ region->height != obj_surface->orig_height) {
+ if (!i965_draw_region_reset(ctx, obj_surface))
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
assert(region->bo);
- /* Check buffer link */
- va_status = va_surface_relink_buffer(ctx, va_wl_surface);
- if (va_status != VA_STATUS_SUCCESS)
- return va_status;
/* Render to RGBA surface */
va_surface = obj_surface->base.id;
@@ -272,45 +134,55 @@ va_attach_rgb_surface(
}
static VAStatus
-va_wayland_attach_surface_unlocked(
+i965_wayland_get_buffer_unlocked(
VADriverContextP ctx,
- struct va_wl_surface *va_wl_surface,
struct object_surface *obj_surface,
- unsigned int flags
-)
+ struct wl_buffer **out_buffer
+ )
{
VAStatus va_status;
-
- va_status = va_attach_rgb_surface(ctx, va_wl_surface, obj_surface, flags);
+ struct VADriverVTableWayland * const vtable = ctx->vtable_wayland;
+ int format = 0;
+
+ // XXXX todo
+ switch (obj_surface->fourcc) {
+ case VA_FOURCC_NV12:
+
+ break;
+ default:
+ break;
+ }
+
+#if 1
+ // todo, when YUV buffer is supported in weston/mesa, we can skip color conversion here
+ format = VA_WL_FORMAT_RGBA;
+ va_status = i965_render_surface_rgb(ctx, obj_surface, 0); // set flags to 0
if (va_status != VA_STATUS_SUCCESS)
return va_status;
-
- if (!va_wl_surface->wl_buffer) {
- va_wl_surface->wl_buffer = wl_drm_create_buffer(
- va_wl_surface->wl_drm,
- va_wl_surface->name,
- va_wl_surface->width,
- va_wl_surface->height,
- va_wl_surface->region.pitch,
- va_wl_surface->format
- );
- if (!va_wl_surface->wl_buffer)
- return VA_STATUS_ERROR_ALLOCATION_FAILED;
-
- wl_surface_attach(
- va_wl_surface->wl_surface,
- va_wl_surface->wl_buffer,
- 0, 0
+#endif
+
+ // always create a new wl_buffer, right?
+ // todo, consider YUV format here
+ struct wl_buffer *buffer;
+ buffer = wl_drm_create_buffer(
+ vtable->wl_drm,
+ vtable->name,
+ obj_surface->orig_width,
+ obj_surface->orig_height,
+ obj_surface->width*4,
+ format
);
+ if (!buffer) {
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
+ *out_buffer = buffer;
- wl_surface_damage(
- va_wl_surface->wl_surface,
- 0, 0, va_wl_surface->width, va_wl_surface->height
- );
-
- obj_surface->flags |= SURFACE_DISPLAYED;
+ // todo, should we add new API to let app set this flag up?
+ // obj_surface->flags |= SURFACE_DISPLAYED;
+ // who is responsible for releasing this bo?
+ // for YUV buffer, we'd comment it out
+ #if 1
if ((obj_surface->flags & SURFACE_ALL_MASK) == SURFACE_DISPLAYED) {
dri_bo_unreference(obj_surface->bo);
obj_surface->bo = NULL;
@@ -319,15 +191,16 @@ va_wayland_attach_surface_unlocked(
if (obj_surface->free_private_data)
obj_surface->free_private_data(&obj_surface->private_data);
}
+ #endif
+
return VA_STATUS_SUCCESS;
}
static VAStatus
-va_wayland_attach_surface(
+i965_wayland_get_buffer(
VADriverContextP ctx,
- struct va_wl_surface *va_wl_surface,
VASurfaceID va_surface,
- unsigned int flags
+ struct wl_buffer **out_buffer
)
{
struct i965_driver_data * const i965 = i965_driver_data(ctx);
@@ -336,28 +209,59 @@ va_wayland_attach_surface(
if (ctx->display_type != VA_DISPLAY_WAYLAND)
return VA_STATUS_ERROR_INVALID_DISPLAY;
- if (!va_wl_surface)
- return VA_STATUS_ERROR_INVALID_SURFACE;
obj_surface = SURFACE(va_surface);
if (!obj_surface || !obj_surface->bo)
return VA_STATUS_ERROR_INVALID_SURFACE;
_i965LockMutex(&i965->render_mutex);
- va_status = va_wayland_attach_surface_unlocked(
+ va_status = i965_wayland_get_buffer_unlocked(
ctx,
- va_wl_surface,
obj_surface,
- flags
+ out_buffer
);
+
_i965UnlockMutex(&i965->render_mutex);
return va_status;
}
+
bool
i965_render_wayland_init(VADriverContextP ctx)
{
struct VADriverVTableWayland * const vtable = ctx->vtable_wayland;
+ uint32_t id;
+
+ if (ctx->display_type != VA_DISPLAY_WAYLAND)
+ return true;
+
+ if (!vtable)
+ return false;
+
+ vtable->wl_drm = NULL;
+ vtable->name = 0;
+ vtable->vaGetSurfaceBufferWl = i965_wayland_get_buffer;
+
+ id = wl_display_get_global(ctx->native_dpy, "wl_drm", 1);
+ if (!id) {
+ wl_display_roundtrip(ctx->native_dpy);
+ id = wl_display_get_global(ctx->native_dpy, "wl_drm", 1);
+ if (!id)
+ return VA_STATUS_ERROR_INVALID_DISPLAY;
+ }
+
+ vtable->wl_drm =
+ wl_display_bind(ctx->native_dpy, id, &wl_drm_interface);
+ if (!vtable->wl_drm)
+ return VA_STATUS_ERROR_INVALID_DISPLAY;
+ return true;
+}
+
+// todo, I can't find a deinit func in i965_drv_video.c to call it.
+bool
+i965_render_wayland_terminate(VADriverContextP ctx)
+{
+ struct VADriverVTableWayland * const vtable = ctx->vtable_wayland;
if (ctx->display_type != VA_DISPLAY_WAYLAND)
return true;
@@ -365,8 +269,11 @@ i965_render_wayland_init(VADriverContextP ctx)
if (!vtable)
return false;
- vtable->vaCreateSurfaceWL = va_wayland_create_surface;
- vtable->vaDestroySurfaceWL = va_wayland_destroy_surface;
- vtable->vaAttachSurfaceWL = va_wayland_attach_surface;
+ if (vtable->wl_drm) {
+ wl_drm_destroy(vtable->wl_drm);
+ vtable->wl_drm = NULL;
+ }
+
return true;
}
+
diff --git a/src/i965_render_wayland.h b/src/i965_render_wayland.h
index 1418c71..b65e954 100755
--- a/src/i965_render_wayland.h
+++ b/src/i965_render_wayland.h
@@ -29,5 +29,7 @@
bool
i965_render_wayland_init(VADriverContextP ctx);
+bool
+i965_render_wayland_terminate(VADriverContextP ctx);
#endif /* I965_RENDER_WAYLAND_H */
--
1.7.5.4
More information about the Libva
mailing list