pixman-renderer: track Pixman formats in pixel format table

Adds a Pixman format field to the pixel format table, and
adjusts the shm format handling code in the Pixman renderer
to use this table.

Pixman formats have been registered only for specific 565, 8888,
and 2101010 layouts, as these have corresponding DRM format codes
and are commonly used.

Signed-off-by: Manuel Stoeckl <code@mstoeckl.com>
dev
Manuel Stoeckl 3 years ago committed by Marius Vlad
parent 448f05e82d
commit 8a7f1e2bc0
  1. 67
      libweston/pixel-formats.c
  2. 25
      libweston/pixel-formats.h
  3. 42
      libweston/pixman-renderer.c

@ -65,6 +65,8 @@
.bits.a = a_, \
.component_type = PIXEL_COMPONENT_TYPE_FIXED
#define PIXMAN_FMT(fmt) .pixman_format = (PIXMAN_ ## fmt)
#include "shared/weston-egl-ext.h"
/**
@ -171,6 +173,7 @@ static const struct pixel_format_info pixel_format_table[] = {
# if __BYTE_ORDER == __LITTLE_ENDIAN
GL_FORMAT(GL_RGB),
GL_TYPE(GL_UNSIGNED_SHORT_5_6_5),
PIXMAN_FMT(r5g6b5),
#endif
},
{
@ -194,6 +197,11 @@ static const struct pixel_format_info pixel_format_table[] = {
.bpp = 32,
GL_FORMAT(GL_BGRA_EXT),
GL_TYPE(GL_UNSIGNED_BYTE),
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(x8r8g8b8),
#else
PIXMAN_FMT(b8g8r8x8),
#endif
},
{
DRM_FORMAT(ARGB8888),
@ -203,12 +211,22 @@ static const struct pixel_format_info pixel_format_table[] = {
.bpp = 32,
GL_FORMAT(GL_BGRA_EXT),
GL_TYPE(GL_UNSIGNED_BYTE),
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(a8r8g8b8),
#else
PIXMAN_FMT(b8g8r8a8),
#endif
},
{
DRM_FORMAT(XBGR8888),
BITS_RGBA_FIXED(8, 8, 8, 0),
GL_FORMAT(GL_RGBA),
GL_TYPE(GL_UNSIGNED_BYTE),
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(x8b8g8r8),
#else
PIXMAN_FMT(r8g8b8x8),
#endif
},
{
DRM_FORMAT(ABGR8888),
@ -216,35 +234,66 @@ static const struct pixel_format_info pixel_format_table[] = {
.opaque_substitute = DRM_FORMAT_XBGR8888,
GL_FORMAT(GL_RGBA),
GL_TYPE(GL_UNSIGNED_BYTE),
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(a8b8g8r8),
#else
PIXMAN_FMT(r8g8b8a8),
#endif
},
{
DRM_FORMAT(RGBX8888),
BITS_RGBA_FIXED(8, 8, 8, 0),
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(r8g8b8x8),
#else
PIXMAN_FMT(x8b8g8r8),
#endif
},
{
DRM_FORMAT(RGBA8888),
BITS_RGBA_FIXED(8, 8, 8, 8),
.opaque_substitute = DRM_FORMAT_RGBX8888,
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(r8g8b8a8),
#else
PIXMAN_FMT(a8b8g8r8),
#endif
},
{
DRM_FORMAT(BGRX8888),
BITS_RGBA_FIXED(8, 8, 8, 0),
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(b8g8r8x8),
#else
PIXMAN_FMT(x8r8g8b8),
#endif
},
{
DRM_FORMAT(BGRA8888),
BITS_RGBA_FIXED(8, 8, 8, 8),
.opaque_substitute = DRM_FORMAT_BGRX8888,
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(b8g8r8a8),
#else
PIXMAN_FMT(a8r8g8b8),
#endif
},
{
DRM_FORMAT(XRGB2101010),
BITS_RGBA_FIXED(10, 10, 10, 0),
.depth = 30,
.bpp = 32,
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(x2r10g10b10),
#endif
},
{
DRM_FORMAT(ARGB2101010),
BITS_RGBA_FIXED(10, 10, 10, 2),
.opaque_substitute = DRM_FORMAT_XRGB2101010,
#if __BYTE_ORDER == __LITTLE_ENDIAN
PIXMAN_FMT(a2r10g10b10),
#endif
},
{
DRM_FORMAT(XBGR2101010),
@ -252,6 +301,7 @@ static const struct pixel_format_info pixel_format_table[] = {
# if __BYTE_ORDER == __LITTLE_ENDIAN
GL_FORMAT(GL_RGBA),
GL_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV_EXT),
PIXMAN_FMT(x2b10g10r10),
#endif
},
{
@ -261,6 +311,7 @@ static const struct pixel_format_info pixel_format_table[] = {
# if __BYTE_ORDER == __LITTLE_ENDIAN
GL_FORMAT(GL_RGBA),
GL_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV_EXT),
PIXMAN_FMT(a2b10g10r10),
#endif
},
{
@ -447,6 +498,22 @@ pixel_format_get_info(uint32_t format)
return NULL;
}
WL_EXPORT const struct pixel_format_info *
pixel_format_get_info_by_index(unsigned int index)
{
if (index >= ARRAY_LENGTH(pixel_format_table))
return NULL;
return &pixel_format_table[index];
}
WL_EXPORT unsigned int
pixel_format_get_info_count(void)
{
return ARRAY_LENGTH(pixel_format_table);
}
WL_EXPORT const struct pixel_format_info *
pixel_format_get_info_by_drm_name(const char *drm_format_name)
{

@ -26,6 +26,7 @@
#include <inttypes.h>
#include <stdbool.h>
#include <pixman.h>
/**
* Contains information about pixel formats, mapping format codes from
@ -70,6 +71,9 @@ struct pixel_format_info {
/** GL data type, if data can be natively/directly uploaded. */
int gl_type;
/** Pixman data type, if it agrees exactly with the wl_shm format */
pixman_format_code_t pixman_format;
/** If set, this format can be used with the legacy drmModeAddFB()
* function (not AddFB2), using this and the bpp member. */
int depth;
@ -142,6 +146,27 @@ pixel_format_get_info(uint32_t format);
const struct pixel_format_info *
pixel_format_get_info_shm(uint32_t format);
/**
* Get pixel format information by table index
*
* Given a 0-based index in the format table, return the corresponding
* DRM pixel format info structure.
*
* @param index Index of the pixel format in the table
* @returns A pixel format structure (must not be freed), or NULL if the
* index is out of range.
*/
const struct pixel_format_info *
pixel_format_get_info_by_index(unsigned int index);
/**
* Return the size of the pixel format table
*
* @returns The number of entries in the pixel format table
*/
unsigned int
pixel_format_get_info_count(void);
/**
* Get pixel format information for a named DRM format
*

@ -34,6 +34,7 @@
#include "pixman-renderer.h"
#include "color.h"
#include "pixel-formats.h"
#include "shared/helpers.h"
#include <linux/input.h>
@ -623,7 +624,7 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
{
struct pixman_surface_state *ps = get_surface_state(es);
struct wl_shm_buffer *shm_buffer;
pixman_format_code_t pixman_format;
const struct pixel_format_info *pixel_info;
weston_buffer_reference(&ps->buffer_ref, buffer);
weston_buffer_release_reference(&ps->buffer_release_ref,
@ -651,20 +652,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
return;
}
switch (wl_shm_buffer_get_format(shm_buffer)) {
case WL_SHM_FORMAT_XRGB8888:
pixman_format = PIXMAN_x8r8g8b8;
es->is_opaque = true;
break;
case WL_SHM_FORMAT_ARGB8888:
pixman_format = PIXMAN_a8r8g8b8;
es->is_opaque = false;
break;
case WL_SHM_FORMAT_RGB565:
pixman_format = PIXMAN_r5g6b5;
es->is_opaque = true;
break;
default:
pixel_info = pixel_format_get_info_shm(wl_shm_buffer_get_format(shm_buffer));
if (!pixel_info || !pixman_format_supported_source(pixel_info->pixman_format)) {
weston_log("Unsupported SHM buffer format 0x%x\n",
wl_shm_buffer_get_format(shm_buffer));
weston_buffer_reference(&ps->buffer_ref, NULL);
@ -672,14 +661,15 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
weston_buffer_send_server_error(buffer,
"disconnecting due to unhandled buffer type");
return;
break;
}
es->is_opaque = pixel_format_is_opaque(pixel_info);
buffer->shm_buffer = shm_buffer;
buffer->width = wl_shm_buffer_get_width(shm_buffer);
buffer->height = wl_shm_buffer_get_height(shm_buffer);
ps->image = pixman_image_create_bits(pixman_format,
ps->image = pixman_image_create_bits(pixel_info->pixman_format,
buffer->width, buffer->height,
wl_shm_buffer_get_data(shm_buffer),
wl_shm_buffer_get_stride(shm_buffer));
@ -864,6 +854,8 @@ WL_EXPORT int
pixman_renderer_init(struct weston_compositor *ec)
{
struct pixman_renderer *renderer;
const struct pixel_format_info *pixel_info, *info_argb8888, *info_xrgb8888;
unsigned int i, num_formats;
renderer = zalloc(sizeof *renderer);
if (renderer == NULL)
@ -889,7 +881,21 @@ pixman_renderer_init(struct weston_compositor *ec)
weston_compositor_add_debug_binding(ec, KEY_R,
debug_binding, ec);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
info_argb8888 = pixel_format_get_info_shm(WL_SHM_FORMAT_ARGB8888);
info_xrgb8888 = pixel_format_get_info_shm(WL_SHM_FORMAT_XRGB8888);
num_formats = pixel_format_get_info_count();
for (i = 0; i < num_formats; i++) {
pixel_info = pixel_format_get_info_by_index(i);
if (!pixman_format_supported_source(pixel_info->pixman_format))
continue;
/* skip formats which libwayland registers by default */
if (pixel_info == info_argb8888 || pixel_info == info_xrgb8888)
continue;
wl_display_add_shm_format(ec->wl_display, pixel_info->format);
}
wl_signal_init(&renderer->destroy_signal);

Loading…
Cancel
Save