summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorAlexander Preisinger <alexander.preisinger@gmail.com>2013-08-26 18:36:16 +0200
committerAlexander Preisinger <alexander.preisinger@gmail.com>2013-08-26 20:34:06 +0200
commit65321f081dc4c4993eb920391406444f24d73a05 (patch)
tree1398fc391d42ff237107d124e690cf8367781d67 /video
parent56644b8abcb5478f7ba316efbcb3fb4facd7c418 (diff)
downloadmpv-65321f081dc4c4993eb920391406444f24d73a05.tar.bz2
mpv-65321f081dc4c4993eb920391406444f24d73a05.tar.xz
wayland/shm: rework format handling
Use a linked list for all supported formats and make the format table const.
Diffstat (limited to 'video')
-rw-r--r--video/out/vo_wayland.c123
1 files changed, 76 insertions, 47 deletions
diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c
index cd39158250..04e3078ee8 100644
--- a/video/out/vo_wayland.c
+++ b/video/out/vo_wayland.c
@@ -49,43 +49,42 @@ static const struct wl_shm_listener shm_listener;
struct fmtentry {
enum wl_shm_format wl_fmt;
enum mp_imgfmt mp_fmt;
- bool hw_support;
};
// the first 2 Formats should be available on most platforms
// all other formats are optional
// the waylad byte order is reversed
-static struct fmtentry fmttable[] = {
- {WL_SHM_FORMAT_ARGB8888, IMGFMT_BGRA, false}, // 8b 8g 8r 8a
- {WL_SHM_FORMAT_XRGB8888, IMGFMT_BGR0, false},
- {WL_SHM_FORMAT_RGB332, IMGFMT_BGR8, false}, // 3b 3g 2r
- {WL_SHM_FORMAT_BGR233, IMGFMT_RGB8, false}, // 3r 3g 3b,
- {WL_SHM_FORMAT_XRGB4444, IMGFMT_BGR12_LE, false}, // 4b 4g 4r 4a
- {WL_SHM_FORMAT_XBGR4444, IMGFMT_RGB12_LE, false}, // 4r 4g 4b 4a
- {WL_SHM_FORMAT_RGBX4444, IMGFMT_RGB12_BE, false}, // 4a 4b 4g 4r
- {WL_SHM_FORMAT_BGRX4444, IMGFMT_BGR12_BE, false}, // 4a 4r 4g 4b
- {WL_SHM_FORMAT_ARGB4444, IMGFMT_BGR12_LE, false},
- {WL_SHM_FORMAT_ABGR4444, IMGFMT_RGB12_LE, false},
- {WL_SHM_FORMAT_RGBA4444, IMGFMT_RGB12_BE, false},
- {WL_SHM_FORMAT_BGRA4444, IMGFMT_BGR12_BE, false},
- {WL_SHM_FORMAT_XRGB1555, IMGFMT_BGR15_LE, false}, // 5b 5g 5r 1a
- {WL_SHM_FORMAT_XBGR1555, IMGFMT_RGB15_LE, false}, // 5r 5g 5b 1a
- {WL_SHM_FORMAT_RGBX5551, IMGFMT_RGB15_BE, false}, // 1a 5g 5b 5r
- {WL_SHM_FORMAT_BGRX5551, IMGFMT_BGR15_BE, false}, // 1a 5r 5g 5b
- {WL_SHM_FORMAT_ARGB1555, IMGFMT_BGR15_LE, false},
- {WL_SHM_FORMAT_ABGR1555, IMGFMT_RGB15_LE, false},
- {WL_SHM_FORMAT_RGBA5551, IMGFMT_RGB15_BE, false},
- {WL_SHM_FORMAT_BGRA5551, IMGFMT_BGR15_BE, false},
- {WL_SHM_FORMAT_RGB565, IMGFMT_BGR16_LE, false}, // 5b 6g 5r
- {WL_SHM_FORMAT_BGR565, IMGFMT_RGB16_LE, false}, // 5r 6g 5b
- {WL_SHM_FORMAT_RGB888, IMGFMT_BGR24, false}, // 8b 8g 8r
- {WL_SHM_FORMAT_BGR888, IMGFMT_RGB24, false}, // 8r 8g 8b
- {WL_SHM_FORMAT_XBGR8888, IMGFMT_RGB0, false},
- {WL_SHM_FORMAT_RGBX8888, IMGFMT_0BGR, false},
- {WL_SHM_FORMAT_BGRX8888, IMGFMT_0RGB, false},
- {WL_SHM_FORMAT_ABGR8888, IMGFMT_RGBA, false},
- {WL_SHM_FORMAT_RGBA8888, IMGFMT_ABGR, false},
- {WL_SHM_FORMAT_BGRA8888, IMGFMT_ARGB, false},
+static const struct fmtentry fmttable[] = {
+ {WL_SHM_FORMAT_ARGB8888, IMGFMT_BGRA}, // 8b 8g 8r 8a
+ {WL_SHM_FORMAT_XRGB8888, IMGFMT_BGR0},
+ {WL_SHM_FORMAT_RGB332, IMGFMT_BGR8}, // 3b 3g 2r
+ {WL_SHM_FORMAT_BGR233, IMGFMT_RGB8}, // 3r 3g 3b,
+ {WL_SHM_FORMAT_XRGB4444, IMGFMT_BGR12_LE}, // 4b 4g 4r 4a
+ {WL_SHM_FORMAT_XBGR4444, IMGFMT_RGB12_LE}, // 4r 4g 4b 4a
+ {WL_SHM_FORMAT_RGBX4444, IMGFMT_RGB12_BE}, // 4a 4b 4g 4r
+ {WL_SHM_FORMAT_BGRX4444, IMGFMT_BGR12_BE}, // 4a 4r 4g 4b
+ {WL_SHM_FORMAT_ARGB4444, IMGFMT_BGR12_LE},
+ {WL_SHM_FORMAT_ABGR4444, IMGFMT_RGB12_LE},
+ {WL_SHM_FORMAT_RGBA4444, IMGFMT_RGB12_BE},
+ {WL_SHM_FORMAT_BGRA4444, IMGFMT_BGR12_BE},
+ {WL_SHM_FORMAT_XRGB1555, IMGFMT_BGR15_LE}, // 5b 5g 5r 1a
+ {WL_SHM_FORMAT_XBGR1555, IMGFMT_RGB15_LE}, // 5r 5g 5b 1a
+ {WL_SHM_FORMAT_RGBX5551, IMGFMT_RGB15_BE}, // 1a 5g 5b 5r
+ {WL_SHM_FORMAT_BGRX5551, IMGFMT_BGR15_BE}, // 1a 5r 5g 5b
+ {WL_SHM_FORMAT_ARGB1555, IMGFMT_BGR15_LE},
+ {WL_SHM_FORMAT_ABGR1555, IMGFMT_RGB15_LE},
+ {WL_SHM_FORMAT_RGBA5551, IMGFMT_RGB15_BE},
+ {WL_SHM_FORMAT_BGRA5551, IMGFMT_BGR15_BE},
+ {WL_SHM_FORMAT_RGB565, IMGFMT_BGR16_LE}, // 5b 6g 5r
+ {WL_SHM_FORMAT_BGR565, IMGFMT_RGB16_LE}, // 5r 6g 5b
+ {WL_SHM_FORMAT_RGB888, IMGFMT_BGR24}, // 8b 8g 8r
+ {WL_SHM_FORMAT_BGR888, IMGFMT_RGB24}, // 8r 8g 8b
+ {WL_SHM_FORMAT_XBGR8888, IMGFMT_RGB0},
+ {WL_SHM_FORMAT_RGBX8888, IMGFMT_0BGR},
+ {WL_SHM_FORMAT_BGRX8888, IMGFMT_0RGB},
+ {WL_SHM_FORMAT_ABGR8888, IMGFMT_RGBA},
+ {WL_SHM_FORMAT_RGBA8888, IMGFMT_ABGR},
+ {WL_SHM_FORMAT_BGRA8888, IMGFMT_ARGB},
};
#define MAX_FORMAT_ENTRIES (sizeof(fmttable) / sizeof(fmttable[0]))
@@ -100,11 +99,18 @@ struct buffer {
size_t shm_size;
};
+struct supported_format {
+ const struct fmtentry *fmt;
+ bool is_alpha;
+ struct wl_list link;
+};
+
struct priv {
struct vo *vo;
struct vo_wayland_state *wl;
- struct fmtentry *pref_format;
+ struct wl_list format_list;
+ const struct fmtentry *pref_format;
int bytes_per_pixel;
int stride;
@@ -207,6 +213,11 @@ static int os_create_anonymous_file(off_t size)
return fd;
}
+static bool is_alpha_format(const struct fmtentry *fmt)
+{
+ return !!(mp_imgfmt_get_desc(fmt->mp_fmt).flags & MP_IMGFLAG_ALPHA);
+}
+
static void buffer_swap(struct priv *p)
{
if (!p->back_buffer->is_new)
@@ -459,7 +470,10 @@ static void shm_handle_format(void *data,
if (fmttable[i].wl_fmt == format) {
MP_INFO(p->vo, "format %s supported by hw\n",
mp_imgfmt_to_name(fmttable[i].mp_fmt));
- fmttable[i].hw_support = true;
+ struct supported_format *sf = talloc(p, struct supported_format);
+ sf->fmt = &fmttable[i];
+ sf->is_alpha = is_alpha_format(sf->fmt);
+ wl_list_insert(&p->format_list, &sf->link);
}
}
}
@@ -511,8 +525,10 @@ static void flip_page(struct vo *vo)
static int query_format(struct vo *vo, uint32_t format)
{
- for (int i = 0; i < MAX_FORMAT_ENTRIES; ++i) {
- if (fmttable[i].mp_fmt == format && fmttable[i].hw_support)
+ struct priv *p = vo->priv;
+ struct supported_format *sf;
+ wl_list_for_each_reverse(sf, &p->format_list, link) {
+ if (sf->fmt->mp_fmt == format)
return VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_CSP_SUPPORTED;
}
@@ -531,24 +547,35 @@ static int reconfig(struct vo *vo, struct mp_image_params *fmt, int flags)
p->height = vo->dheight;
p->in_format = *fmt;
+ struct supported_format *sf;
+
// find the same format first
- for (int i = 0; !p->pref_format && i < MAX_FORMAT_ENTRIES; ++i) {
- if (fmttable[i].mp_fmt == fmt->imgfmt && fmttable[i].hw_support)
- p->pref_format = &fmttable[i];
+ wl_list_for_each(sf, &p->format_list, link) {
+ if (sf->fmt->mp_fmt == fmt->imgfmt && (p->enable_alpha == sf->is_alpha)) {
+ p->pref_format = sf->fmt;
+ break;
+ }
}
// if the format is not supported choose one of the fancy formats next
- // the default formats are always first so begin with the last
- for (int i = MAX_FORMAT_ENTRIES-1; !p->pref_format && i >= 0; --i) {
- if (fmttable[i].hw_support)
- p->pref_format = &fmttable[i];
+ // the default formats are always last
+ if (!p->pref_format) {
+ wl_list_for_each(sf, &p->format_list, link) {
+ if (p->enable_alpha == sf->is_alpha) {
+ p->pref_format = sf->fmt;
+ break;
+ }
+ }
}
- if (p->use_default)
- p->pref_format = &fmttable[DEFAULT_FORMAT_ENTRY];
+ // if use default is enable overwrite the auto selected one
+ if (p->use_default) {
+ if (p->enable_alpha)
+ p->pref_format = &fmttable[DEFAULT_ALPHA_FORMAT_ENTRY];
+ else
+ p->pref_format = &fmttable[DEFAULT_FORMAT_ENTRY];
+ }
- if (p->enable_alpha)
- p->pref_format = &fmttable[DEFAULT_ALPHA_FORMAT_ENTRY];
p->bytes_per_pixel = mp_imgfmt_get_desc(p->pref_format->mp_fmt).bytes[0];
MP_VERBOSE(vo, "bytes per pixel: %d\n", p->bytes_per_pixel);
@@ -590,6 +617,8 @@ static int preinit(struct vo *vo)
p->front_buffer = &p->buffers[1];
p->back_buffer = &p->buffers[0];
+ wl_list_init(&p->format_list);
+
wl_shm_add_listener(p->wl->display.shm, &shm_listener, p);
wl_display_dispatch(p->wl->display.display);
return 0;