diff options
author | Niels De Graef <Niels.DeGraef@barco.com> | 2018-11-14 12:22:02 +0100 |
---|---|---|
committer | Niels De Graef <niels.degraef@barco.com> | 2019-06-03 16:06:23 +0200 |
commit | a3fb239344b9455e94c5489be40a98ac53de5468 (patch) | |
tree | 555d1f6ce305dd2442f5b03150109121698d16d1 /cogl/cogl/cogl-pixel-format.c | |
parent | d3ed857ebc346727c2ce12c3fa2ecfa1bd10a37d (diff) | |
download | mutter-a3fb239344b9455e94c5489be40a98ac53de5468.tar.gz |
WIP: wayland: add basic support for non-RGBA textureswip/nielsdg/add-yuv-support-gnome-3-32
Up until now, we didn't support sending YUV textures to the Wayland
server. This was for several reasons:
* We draw onto an RGBA framebuffer, so any other color format needs to
be converted to that color space. Since we don't want to lose a lot of
performance, this is ideally done on the GPU (using shaders).
* YUV formats can consist of several planes (for example NV12, a common
format in decoded video frames consists of a Y-plane and a subsampled
UV-plane). Mutter always assumed that any texture it got was
representable by a `CoglTexture`, which does not have this kind of
concept.
To deal with this, we introduce a new "texture": a
`CoglMultiPlaneTexture` which consists of multiple CoglTextures, each
representing a plane in the texture we got. It also provides support
for CoglSnippets which can convert the colorspace if necessary.
What changes are in this commit:
* Introduce a new CoglMultiPlaneTexture object. Right now it is not
implemented as a CoglTexture to prevent any confusion (but it is
somewhat related to CoglMetaTexture)
* Added some extra values to the CoglPixelFormat enum that deal with YUV
* Make the necessary changes in MetaWaylandBuffer, so that it knows how
to deal with incoming buffers (for example EGLImages and shm buffers)
* This also introduces some changes in MetaDmaBuf, as that is also a
different kind of buffer we can receive from wayland.
Acknowledgements
* There was a lot of prior art already done by the authors of Weston,
CoglGstVideoSink and ClutterGstSink
* My employer Barco for allowing me to work on this
Diffstat (limited to 'cogl/cogl/cogl-pixel-format.c')
-rw-r--r-- | cogl/cogl/cogl-pixel-format.c | 439 |
1 files changed, 408 insertions, 31 deletions
diff --git a/cogl/cogl/cogl-pixel-format.c b/cogl/cogl/cogl-pixel-format.c index a8c0857a6..4225c6de1 100644 --- a/cogl/cogl/cogl-pixel-format.c +++ b/cogl/cogl/cogl-pixel-format.c @@ -43,6 +43,7 @@ typedef struct _CoglPixelFormatInfo const char *format_str; int bpp; /* Bytes per pixel */ int aligned; /* Aligned components? (-1 if n/a) */ + uint8_t n_planes; } CoglPixelFormatInfo; static const CoglPixelFormatInfo format_info_table[] = { @@ -50,187 +51,425 @@ static const CoglPixelFormatInfo format_info_table[] = { .cogl_format = COGL_PIXEL_FORMAT_ANY, .format_str = "ANY", .bpp = 0, - .aligned = -1 + .aligned = -1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_A_8, .format_str = "A_8", .bpp = 1, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGB_565, .format_str = "RGB_565", .bpp = 2, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444, .format_str = "RGBA_4444", .bpp = 2, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551, .format_str = "RGBA_5551", .bpp = 2, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_YUV, .format_str = "YUV", .bpp = 0, - .aligned = -1 + .aligned = -1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_G_8, .format_str = "G_8", .bpp = 1, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RG_88, .format_str = "RG_88", .bpp = 2, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGB_888, .format_str = "RGB_888", .bpp = 3, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_BGR_888, .format_str = "BGR_888", .bpp = 3, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888, .format_str = "RGBA_8888", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888, .format_str = "BGRA_8888", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888, .format_str = "ARGB_8888", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888, .format_str = "ABGR_8888", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102, .format_str = "RGBA_1010102", .bpp = 4, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102, .format_str = "BGRA_1010102", .bpp = 4, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010, .format_str = "ARGB_2101010", .bpp = 4, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010, .format_str = "ABGR_2101010", .bpp = 4, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE, .format_str = "RGBA_8888_PRE", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_BGRA_8888_PRE, .format_str = "BGRA_8888_PRE", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_ARGB_8888_PRE, .format_str = "ARGB_8888_PRE", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_ABGR_8888_PRE, .format_str = "ABGR_8888_PRE", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_4444_PRE, .format_str = "RGBA_4444_PRE", .bpp = 2, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_5551_PRE, .format_str = "RGBA_5551_PRE", .bpp = 2, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_RGBA_1010102_PRE, .format_str = "RGBA_1010102_PRE", .bpp = 4, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_BGRA_1010102_PRE, .format_str = "BGRA_1010102_PRE", .bpp = 4, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_ARGB_2101010_PRE, .format_str = "ARGB_2101010_PRE", .bpp = 4, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_ABGR_2101010_PRE, .format_str = "ABGR_2101010_PRE", .bpp = 4, - .aligned = 0 + .aligned = 0, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_DEPTH_16, .format_str = "DEPTH_16", .bpp = 2, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_DEPTH_32, .format_str = "DEPTH_32", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 }, { .cogl_format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8, .format_str = "DEPTH_24_STENCIL_8", .bpp = 4, - .aligned = 1 + .aligned = 1, + .n_planes = 1 + }, + /* Packed YUV */ + { + .cogl_format = COGL_PIXEL_FORMAT_YUYV, + .format_str = "YUYV", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVYU, + .format_str = "YVYU", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_UYVY, + .format_str = "UYVY", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_VYUY, + .format_str = "VYUY", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_AYUV, + .format_str = "AYUV", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + /* 2 plane RGB + A */ + { + .cogl_format = COGL_PIXEL_FORMAT_XRGB88888_A8, + .format_str = "XRGB88888_A8", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_XBGR88888_A8, + .format_str = "XBGR88888_A8", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGBX88888_A8, + .format_str = "RGBX88888_A8", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGRX88888_A8, + .format_str = "BGRX88888_A8", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGB888_A8, + .format_str = "RGB888_A8", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGR888_A8, + .format_str = "BGR888_A8", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_RGB565_A8, + .format_str = "RGB565_A8", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_BGR565_A8, + .format_str = "BGR565_A8", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + /* 2 plane YUV */ + { + .cogl_format = COGL_PIXEL_FORMAT_NV12, + .format_str = "NV12", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV21, + .format_str = "NV21", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV16, + .format_str = "NV16", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV61, + .format_str = "NV61", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV24, + .format_str = "NV24", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_NV42, + .format_str = "NV42", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + /* 3 plane YUV */ + { + .cogl_format = COGL_PIXEL_FORMAT_YUV410, + .format_str = "YUV410", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU410, + .format_str = "YVU410", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV411, + .format_str = "YUV411", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU411, + .format_str = "YVU411", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV420, + .format_str = "YUV420", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU420, + .format_str = "YVU420", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV422, + .format_str = "YUV422", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU422, + .format_str = "YVU422", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YUV444, + .format_str = "YUV444", + .bpp = -1, + .aligned = 0, + .n_planes = 2 + }, + { + .cogl_format = COGL_PIXEL_FORMAT_YVU444, + .format_str = "YVU444", + .bpp = -1, + .aligned = 0, + .n_planes = 2 }, }; @@ -268,6 +507,45 @@ _cogl_pixel_format_get_bytes_per_pixel (CoglPixelFormat format) g_assert_not_reached (); } +/* + * XXX document. + * + * XXX lol, this is even per macropixel, not per pixel :D + */ +void +cogl_pixel_format_get_bits_per_pixel (CoglPixelFormat format, guint *bpp_out) +{ + /* "old" formats */ + if (format & (0xff << 24)) + { + switch (format) + { + case COGL_PIXEL_FORMAT_NV12: + case COGL_PIXEL_FORMAT_NV21: + bpp_out[0] = 8; + bpp_out[1] = 4; + break; + case COGL_PIXEL_FORMAT_YUV420: + case COGL_PIXEL_FORMAT_YVU420: + bpp_out[0] = 8; + bpp_out[1] = 2; + bpp_out[2] = 2; + break; + default: + g_warning ("FIXME"); + } + } + else + { + int bpp_lut[] = { 0, 1, 3, 4, + 2, 2, 2, 0, + 1, 2, 0, 0, + 3, 4, 0, 0 }; + + bpp_out[0] = 8 * bpp_lut [format & 0xf]; + } +} + /* Note: this also refers to the mapping defined above for * _cogl_pixel_format_get_bytes_per_pixel() */ gboolean @@ -295,6 +573,105 @@ _cogl_pixel_format_is_endian_dependant (CoglPixelFormat format) return aligned; } +guint +cogl_pixel_format_get_n_planes (CoglPixelFormat format) +{ + guint i; + + for (i = 0; i < G_N_ELEMENTS (format_info_table); i++) + { + if (format_info_table[i].cogl_format == format) + return format_info_table[i].n_planes; + } + + g_assert_not_reached (); +} + +void +cogl_pixel_format_get_subsampling_factors (CoglPixelFormat format, + guint *horizontal_factors, + guint *vertical_factors) +{ + switch (format) + { + /* Packed formats (single plane) */ + default: + horizontal_factors[0] = 1; + vertical_factors[0] = 1; + break; + + /* 2 planes */ + case COGL_PIXEL_FORMAT_NV12: + case COGL_PIXEL_FORMAT_NV21: + horizontal_factors[0] = 1; + vertical_factors[0] = 1; + horizontal_factors[1] = 2; + vertical_factors[1] = 2; + break; + + case COGL_PIXEL_FORMAT_XRGB88888_A8: + case COGL_PIXEL_FORMAT_XBGR88888_A8: + case COGL_PIXEL_FORMAT_RGBX88888_A8: + case COGL_PIXEL_FORMAT_BGRX88888_A8: + case COGL_PIXEL_FORMAT_RGB888_A8: + case COGL_PIXEL_FORMAT_BGR888_A8: + case COGL_PIXEL_FORMAT_RGB565_A8: + case COGL_PIXEL_FORMAT_BGR565_A8: + horizontal_factors[0] = 1; + vertical_factors[0] = 1; + horizontal_factors[1] = 1; + vertical_factors[1] = 1; + break; + + /* 3 planes */ + case COGL_PIXEL_FORMAT_YUV410: + case COGL_PIXEL_FORMAT_YVU410: + horizontal_factors[0] = 1; + vertical_factors[0] = 1; + horizontal_factors[1] = 4; + vertical_factors[1] = 4; + horizontal_factors[2] = 4; + vertical_factors[2] = 4; + break; + case COGL_PIXEL_FORMAT_YUV411: + case COGL_PIXEL_FORMAT_YVU411: + horizontal_factors[0] = 1; + vertical_factors[0] = 1; + horizontal_factors[1] = 4; + vertical_factors[1] = 1; + horizontal_factors[2] = 4; + vertical_factors[2] = 1; + break; + case COGL_PIXEL_FORMAT_YUV420: + case COGL_PIXEL_FORMAT_YVU420: + horizontal_factors[0] = 1; + vertical_factors[0] = 1; + horizontal_factors[1] = 2; + vertical_factors[1] = 2; + horizontal_factors[2] = 2; + vertical_factors[2] = 2; + break; + case COGL_PIXEL_FORMAT_YUV422: + case COGL_PIXEL_FORMAT_YVU422: + horizontal_factors[0] = 1; + vertical_factors[0] = 1; + horizontal_factors[1] = 2; + vertical_factors[1] = 1; + horizontal_factors[2] = 2; + vertical_factors[2] = 1; + break; + case COGL_PIXEL_FORMAT_YUV444: + case COGL_PIXEL_FORMAT_YVU444: + horizontal_factors[0] = 1; + vertical_factors[0] = 1; + horizontal_factors[1] = 1; + vertical_factors[1] = 1; + horizontal_factors[2] = 1; + vertical_factors[2] = 1; + break; + } +} + const char * cogl_pixel_format_to_string (CoglPixelFormat format) { |