mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 02:31:03 +00:00
waylandsink: Properly draw black border in absence of viewporter
When we don't have a viewporter (scaling support), we can't use the 1x1 scaleup image trick. Instead, we need to allocate a buffer with the same size as the area that need to have black background.
This commit is contained in:
parent
1489e73df4
commit
ecf88d0d43
2 changed files with 60 additions and 36 deletions
|
@ -102,11 +102,6 @@ static GstWlWindow *
|
|||
gst_wl_window_new_internal (GstWlDisplay * display)
|
||||
{
|
||||
GstWlWindow *window;
|
||||
GstVideoInfo info;
|
||||
GstBuffer *buf;
|
||||
GstMapInfo mapinfo;
|
||||
struct wl_buffer *wlbuf;
|
||||
GstWlBuffer *gwlbuf;
|
||||
struct wl_region *region;
|
||||
|
||||
window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
|
||||
|
@ -132,30 +127,6 @@ gst_wl_window_new_internal (GstWlDisplay * display)
|
|||
window->video_surface);
|
||||
}
|
||||
|
||||
/* draw the area_subsurface */
|
||||
gst_video_info_set_format (&info,
|
||||
/* we want WL_SHM_FORMAT_XRGB8888 */
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
GST_VIDEO_FORMAT_xRGB,
|
||||
#else
|
||||
GST_VIDEO_FORMAT_BGRx,
|
||||
#endif
|
||||
1, 1);
|
||||
|
||||
buf = gst_buffer_new_allocate (gst_wl_shm_allocator_get (), info.size, NULL);
|
||||
gst_buffer_map (buf, &mapinfo, GST_MAP_WRITE);
|
||||
*((guint32 *) mapinfo.data) = 0; /* paint it black */
|
||||
gst_buffer_unmap (buf, &mapinfo);
|
||||
wlbuf =
|
||||
gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0),
|
||||
display, &info);
|
||||
gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, display);
|
||||
gst_wl_buffer_attach (gwlbuf, window->area_surface);
|
||||
|
||||
/* at this point, the GstWlBuffer keeps the buffer
|
||||
* alive and will free it on wl_buffer::release */
|
||||
gst_buffer_unref (buf);
|
||||
|
||||
/* do not accept input */
|
||||
region = wl_compositor_create_region (display->compositor);
|
||||
wl_surface_set_input_region (window->area_surface, region);
|
||||
|
@ -261,7 +232,6 @@ gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
|
|||
|
||||
wl_subsurface_set_position (window->video_subsurface, res.x, res.y);
|
||||
|
||||
|
||||
if (commit) {
|
||||
wl_surface_damage (window->video_surface, 0, 0, res.w, res.h);
|
||||
wl_surface_commit (window->video_surface);
|
||||
|
@ -278,8 +248,7 @@ gst_wl_window_resize_video_surface (GstWlWindow * window, gboolean commit)
|
|||
}
|
||||
|
||||
/* this is saved for use in wl_surface_damage */
|
||||
window->surface_width = res.w;
|
||||
window->surface_height = res.h;
|
||||
window->video_rectangle = res;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -300,8 +269,8 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
|
|||
else
|
||||
wl_surface_attach (window->video_surface, NULL, 0, 0);
|
||||
|
||||
wl_surface_damage (window->video_surface, 0, 0, window->surface_width,
|
||||
window->surface_height);
|
||||
wl_surface_damage (window->video_surface, 0, 0, window->video_rectangle.w,
|
||||
window->video_rectangle.h);
|
||||
wl_surface_commit (window->video_surface);
|
||||
|
||||
if (G_UNLIKELY (info)) {
|
||||
|
@ -316,6 +285,53 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
|
|||
wl_display_flush (window->display->display);
|
||||
}
|
||||
|
||||
/* Update the buffer used to draw black borders. When we have viewporter
|
||||
* support, this is a scaled up 1x1 image, and without we need an black image
|
||||
* the size of the rendering areay. */
|
||||
static void
|
||||
gst_wl_window_update_borders (GstWlWindow * window)
|
||||
{
|
||||
GstVideoFormat format;
|
||||
GstVideoInfo info;
|
||||
gint width, height;
|
||||
GstBuffer *buf;
|
||||
struct wl_buffer *wlbuf;
|
||||
GstWlBuffer *gwlbuf;
|
||||
|
||||
if (window->no_border_update)
|
||||
return;
|
||||
|
||||
if (window->display->viewporter) {
|
||||
width = height = 1;
|
||||
window->no_border_update = TRUE;
|
||||
} else {
|
||||
width = window->render_rectangle.w;
|
||||
height = window->render_rectangle.h;
|
||||
}
|
||||
|
||||
/* we want WL_SHM_FORMAT_XRGB8888 */
|
||||
#if G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
format = GST_VIDEO_FORMAT_xRGB;
|
||||
#else
|
||||
format = GST_VIDEO_FORMAT_BGRx;
|
||||
#endif
|
||||
|
||||
/* draw the area_subsurface */
|
||||
gst_video_info_set_format (&info, format, width, height);
|
||||
|
||||
buf = gst_buffer_new_allocate (gst_wl_shm_allocator_get (), info.size, NULL);
|
||||
gst_buffer_memset (buf, 0, 0, info.size);
|
||||
wlbuf =
|
||||
gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0),
|
||||
window->display, &info);
|
||||
gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, window->display);
|
||||
gst_wl_buffer_attach (gwlbuf, window->area_surface);
|
||||
|
||||
/* at this point, the GstWlBuffer keeps the buffer
|
||||
* alive and will free it on wl_buffer::release */
|
||||
gst_buffer_unref (buf);
|
||||
}
|
||||
|
||||
void
|
||||
gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
|
||||
gint w, gint h)
|
||||
|
@ -335,6 +351,8 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
|
|||
if (window->area_viewport)
|
||||
wp_viewport_set_destination (window->area_viewport, w, h);
|
||||
|
||||
gst_wl_window_update_borders (window);
|
||||
|
||||
if (window->video_width != 0) {
|
||||
wl_subsurface_set_sync (window->video_subsurface);
|
||||
gst_wl_window_resize_video_surface (window, TRUE);
|
||||
|
|
|
@ -52,10 +52,16 @@ struct _GstWlWindow
|
|||
|
||||
/* the size and position of the area_(sub)surface */
|
||||
GstVideoRectangle render_rectangle;
|
||||
|
||||
/* the size and position of the video_subsurface */
|
||||
GstVideoRectangle video_rectangle;
|
||||
|
||||
/* the size of the video in the buffers */
|
||||
gint video_width, video_height;
|
||||
/* the size of the video_(sub)surface */
|
||||
gint surface_width, surface_height;
|
||||
|
||||
/* this will be set when viewporter is available and black background has
|
||||
* already been set on the area_subsurface */
|
||||
gboolean no_border_update;
|
||||
};
|
||||
|
||||
struct _GstWlWindowClass
|
||||
|
|
Loading…
Reference in a new issue