From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Use the new "COLOR_ENCODING" plane property to implement the XV_COLORSPACE port attribute for sprite Xv adaptors. Cc: Jyri Sarha <jsarha@xxxxxx> Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- src/sna/sna.h | 1 + src/sna/sna_display.c | 148 +++++++++++++++++++++++++++++++++++---------- src/sna/sna_video.h | 3 + src/sna/sna_video_sprite.c | 22 ++++++- 4 files changed, 142 insertions(+), 32 deletions(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index 5283ce436a3b..c9097d3db158 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -634,6 +634,7 @@ static inline void sna_present_cancel_flip(struct sna *sna) { } extern unsigned sna_crtc_count_sprites(xf86CrtcPtr crtc); extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, uint32_t rotation); +extern void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc, unsigned idx, int colorspace); extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx); extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc); diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index ea2f148d213c..86aa711f886d 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -222,6 +222,10 @@ struct sna_crtc { uint32_t supported; uint32_t current; } rotation; + struct { + uint32_t prop; + uint64_t values[2]; + } color_encoding; struct list link; } primary; struct list sprites; @@ -3293,17 +3297,124 @@ static const xf86CrtcFuncsRec sna_crtc_funcs = { #endif }; -inline static bool prop_is_rotation(struct drm_mode_get_property *prop) +inline static bool prop_has_type_and_name(const struct drm_mode_get_property *prop, + unsigned int type, const char *name) { - if ((prop->flags & (1 << 5)) == 0) + if ((prop->flags & (1 << type)) == 0) return false; - if (strcmp(prop->name, "rotation")) + if (strcmp(prop->name, name)) return false; return true; } +inline static bool prop_is_rotation(const struct drm_mode_get_property *prop) +{ + return prop_has_type_and_name(prop, 5, "rotation"); +} + +static void parse_rotation_prop(struct sna *sna, struct plane *p, + struct drm_mode_get_property *prop, + uint64_t value) +{ + struct drm_mode_property_enum *enums; + int j; + + p->rotation.prop = prop->prop_id; + p->rotation.current = value; + + DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n", + __FUNCTION__, prop->prop_id, value, prop->count_enum_blobs)); + + enums = malloc(prop->count_enum_blobs * sizeof(struct drm_mode_property_enum)); + if (!enums) + return; + + prop->count_values = 0; + prop->enum_blob_ptr = (uintptr_t)enums; + + if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, prop)) { + free(enums); + return; + } + + /* XXX we assume that the mapping between kernel enum and + * RandR remains fixed for our lifetimes. + */ + VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop->count_enum_blobs)); + for (j = 0; j < prop->count_enum_blobs; j++) { + DBG(("%s: rotation[%d] = %s [%lx]\n", __FUNCTION__, + j, enums[j].name, (long)enums[j].value)); + p->rotation.supported |= 1 << enums[j].value; + } + + free(enums); +} + +inline static bool prop_is_color_encoding(const struct drm_mode_get_property *prop) +{ + return prop_has_type_and_name(prop, 3, "COLOR_ENCODING"); +} + +static void parse_color_encoding_prop(struct sna *sna, struct plane *p, + struct drm_mode_get_property *prop, + uint64_t value) +{ + struct drm_mode_property_enum *enums; + unsigned int supported = 0; + int j; + + DBG(("%s: found color encoding property .id=%d, value=%ld, num_enums=%d\n", + __FUNCTION__, prop->prop_id, (long)value, prop->count_enum_blobs)); + + enums = malloc(prop->count_enum_blobs * sizeof(struct drm_mode_property_enum)); + if (!enums) + return; + + prop->count_values = 0; + prop->enum_blob_ptr = (uintptr_t)enums; + + if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, prop)) { + free(enums); + return; + } + + VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop->count_enum_blobs)); + for (j = 0; j < prop->count_enum_blobs; j++) { + if (!strcmp(enums[j].name, "ITU-R BT.601 YCbCr")) { + p->color_encoding.values[0] = enums[j].value; + supported |= 1 << 0; + } else if (!strcmp(enums[j].name, "ITU-R BT.709 YCbCr")) { + p->color_encoding.values[1] = enums[j].value; + supported |= 1 << 1; + } + } + + free(enums); + + if (supported == 3) + p->color_encoding.prop = prop->prop_id; +} + +void sna_crtc_set_sprite_colorspace(xf86CrtcPtr crtc, + unsigned idx, int colorspace) +{ + struct plane *p; + + assert(to_sna_crtc(crtc)); + + p = lookup_sprite(to_sna_crtc(crtc), idx); + + if (!p->color_encoding.prop) + return; + + drmModeObjectSetProperty(to_sna(crtc->scrn)->kgem.fd, + p->id, DRM_MODE_OBJECT_PLANE, + p->color_encoding.prop, + p->color_encoding.values[colorspace]); +} + static int plane_details(struct sna *sna, struct plane *p) { #define N_STACK_PROPS 32 /* must be a multiple of 2 */ @@ -3360,34 +3471,9 @@ static int plane_details(struct sna *sna, struct plane *p) if (strcmp(prop.name, "type") == 0) { type = values[i]; } else if (prop_is_rotation(&prop)) { - struct drm_mode_property_enum *enums; - - p->rotation.prop = props[i]; - p->rotation.current = values[i]; - - DBG(("%s: found rotation property .id=%d, value=%ld, num_enums=%d\n", - __FUNCTION__, prop.prop_id, (long)values[i], prop.count_enum_blobs)); - enums = malloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)); - if (enums != NULL) { - prop.count_values = 0; - prop.enum_blob_ptr = (uintptr_t)enums; - - if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_GETPROPERTY, &prop) == 0) { - int j; - - /* XXX we assume that the mapping between kernel enum and - * RandR remains fixed for our lifetimes. - */ - VG(VALGRIND_MAKE_MEM_DEFINED(enums, sizeof(*enums)*prop.count_enum_blobs)); - for (j = 0; j < prop.count_enum_blobs; j++) { - DBG(("%s: rotation[%d] = %s [%lx]\n", __FUNCTION__, - j, enums[j].name, (long)enums[j].value)); - p->rotation.supported |= 1 << enums[j].value; - } - } - - free(enums); - } + parse_rotation_prop(sna, p, &prop, values[i]); + } else if (prop_is_color_encoding(&prop)) { + parse_color_encoding_prop(sna, p, &prop, values[i]); } } diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h index 6b1c864ce9d8..6abf6d540b18 100644 --- a/src/sna/sna_video.h +++ b/src/sna/sna_video.h @@ -100,6 +100,9 @@ struct sna_video { unsigned color_key_changed; bool has_color_key; + unsigned colorspace; + unsigned colorspace_changed; + /** YUV data buffers */ struct kgem_bo *old_buf[2]; struct kgem_bo *buf; diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c index 44898a748e1c..f713ba356b41 100644 --- a/src/sna/sna_video_sprite.c +++ b/src/sna/sna_video_sprite.c @@ -69,11 +69,12 @@ struct local_mode_set_plane { #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true) -static Atom xvColorKey, xvAlwaysOnTop, xvSyncToVblank; +static Atom xvColorKey, xvAlwaysOnTop, xvSyncToVblank, xvColorspace; static XvFormatRec formats[] = { {15}, {16}, {24} }; static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_RGB888, XVMC_RGB565 }; static const XvAttributeRec attribs[] = { + { XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE" }, /* BT.601, BT.709 */ { XvSettable | XvGettable, 0, 0xffffff, (char *)"XV_COLORKEY" }, { XvSettable | XvGettable, 0, 1, (char *)"XV_ALWAYS_ON_TOP" }, }; @@ -119,6 +120,10 @@ static int sna_video_sprite_set_attr(ddSetPortAttribute_ARGS) video->color_key = value; RegionEmpty(&video->clip); DBG(("COLORKEY = %ld\n", (long)value)); + } else if (attribute == xvColorspace) { + video->colorspace_changed = ~0; + video->colorspace = value; + DBG(("COLORSPACE = %ld\n", (long)value)); } else if (attribute == xvSyncToVblank) { DBG(("%s: SYNC_TO_VBLANK: %d -> %d\n", __FUNCTION__, video->SyncToVblank, !!value)); @@ -140,6 +145,8 @@ static int sna_video_sprite_get_attr(ddGetPortAttribute_ARGS) if (attribute == xvColorKey) *value = video->color_key; + else if (attribute == xvColorspace) + *value = video->colorspace; else if (attribute == xvAlwaysOnTop) *value = video->AlwaysOnTop; else if (attribute == xvSyncToVblank) @@ -265,6 +272,16 @@ sna_video_sprite_show(struct sna *sna, video->color_key_changed &= ~(1 << pipe); } + if (video->colorspace_changed & (1 << pipe)) { + DBG(("%s: updating colorspace: %x\n", + __FUNCTION__, video->colorspace)); + + sna_crtc_set_sprite_colorspace(crtc, video->idx, + video->colorspace); + + video->colorspace_changed &= ~(1 << pipe); + } + update_dst_box_to_crtc_coords(sna, crtc, dstBox); if (frame->rotation & (RR_Rotate_90 | RR_Rotate_270)) { int tmp = frame->width; @@ -769,6 +786,8 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen) video->alignment = 64; video->color_key = sna_video_sprite_color_key(sna); video->color_key_changed = ~0; + video->colorspace = 1; /* BT.709 */ + video->colorspace_changed = ~0; video->has_color_key = true; video->brightness = -19; /* (255/219) * -16 */ video->contrast = 75; /* 255/219 * 64 */ @@ -789,6 +808,7 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen) adaptor->base_id = adaptor->pPorts[0].id; xvColorKey = MAKE_ATOM("XV_COLORKEY"); + xvColorspace = MAKE_ATOM("XV_COLORSPACE"); xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP"); xvSyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); -- 2.13.6 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx