xf86-video-intel: 2 commits - src/sna/sna_display.c src/sna/sna.h src/sna/sna_video.h src/sna/sna_video_sprite.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Mar 2 15:18:44 UTC 2018
src/sna/sna.h | 1
src/sna/sna_display.c | 177 +++++++++++++++++++++++++++++++++------------
src/sna/sna_video.h | 3
src/sna/sna_video_sprite.c | 22 +++++
4 files changed, 155 insertions(+), 48 deletions(-)
New commits:
commit aa36399cca1250d878a4608528a535faeb0e931a
Author: dom.constant at free.fr <dom.constant at free.fr>
Date: Tue Feb 6 19:57:05 2018 +0100
sna: CustomEDID fix
For my HTPC setup, I'm using the option "CustomEDID".
With this option, output attaching and destroying events leads to
crashes.
The following sequence leads to a crash:
- In xorg.conf: Option "CustomEDID" "HDMI2:/etc/my_edid.bin"
- Starting Xorg
- Connect HDMI2
- Disconnect HDMI2
- Reconnect HDMI2
-> Crash
The crash happens in xf86OutputSetEDID
(xorg/xserver/hw/xfree86/modes/xf86Crtc.c)
at "free(output->MonInfo)". MonInfo is assigned with
sna_output->fake_edid_mon
which is allocated by intel driver in sna_output_load_fake_edid
(src/sna/sna_display.c).
Sequence details:
- Starting Xorg
-> fake_edid_mon is initialized
- Connect HDMI2
-> xf86OutputSetEDID is called:
- MonInfo is NULL
- MonInfo is assigned with fake_edid_mon pointer
- MonInfo is read by Xorg
- Disconnect HDMI2
- Reconnect HDMI2
-> xf86OutputSetEDID is called:
- MonInfo is freed thus also fake_edid_mon
- MonInfo is assigned with fake_edid_mon
- MonInfo is read but it was freed -> CRASH
The fix consists of a new instance of xf86MonPtr for each calls of
xf86OutputSetEDID.
is initialized with fake_edid_raw which render
fake_edid_mon useless.
With this proposal, the behaviour of an EDID override is similar to
a "real" EDID.
Signed-off-by: Dominique Constant <dom.constant at free.fr>
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 091932f7..e7bf6cab 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -267,7 +267,6 @@ struct sna_output {
uint32_t edid_blob_id;
uint32_t edid_len;
void *edid_raw;
- xf86MonPtr fake_edid_mon;
void *fake_edid_raw;
bool has_panel_limits;
@@ -4189,13 +4188,21 @@ static DisplayModePtr
sna_output_override_edid(xf86OutputPtr output)
{
struct sna_output *sna_output = output->driver_private;
+ xf86MonPtr mon = NULL;
+
+ if (sna_output->fake_edid_raw == NULL)
+ return NULL;
- if (sna_output->fake_edid_mon == NULL)
+ mon = xf86InterpretEDID(output->scrn->scrnIndex, sna_output->fake_edid_raw);
+ if (mon == NULL) {
return NULL;
+ }
+
+ mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
+
+ xf86OutputSetEDID(output, mon);
- xf86OutputSetEDID(output, sna_output->fake_edid_mon);
- return xf86DDCGetModes(output->scrn->scrnIndex,
- sna_output->fake_edid_mon);
+ return xf86DDCGetModes(output->scrn->scrnIndex, mon);
}
static DisplayModePtr
@@ -4983,7 +4990,6 @@ sna_output_load_fake_edid(xf86OutputPtr output)
FILE *file;
void *raw;
int size;
- xf86MonPtr mon;
filename = fake_edid_name(output);
if (filename == NULL)
@@ -5015,16 +5021,6 @@ sna_output_load_fake_edid(xf86OutputPtr output)
}
fclose(file);
- mon = xf86InterpretEDID(output->scrn->scrnIndex, raw);
- if (mon == NULL) {
- free(raw);
- goto err;
- }
-
- if (mon && size > 128)
- mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
-
- sna_output->fake_edid_mon = mon;
sna_output->fake_edid_raw = raw;
xf86DrvMsg(output->scrn->scrnIndex, X_CONFIG,
commit 9b4f400190064f9b60f9f3ce3517586124f157ba
Author: Ville Syrjälä <ville.syrjala at linux.intel.com>
Date: Fri Mar 2 13:59:18 2018 +0200
sna: Add XV_COLORSPACE attribute support for sprite Xv adaptors
Use the new "COLOR_ENCODING" plane property to implement the
XV_COLORSPACE port attribute for sprite Xv adaptors.
v2: assert(colorspace < ARRAY_SIZE) (Chris)
Cc: Jyri Sarha <jsarha at ti.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Reviewed-by: Chris Wilson <chris at chris-wilson.co.uk>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 5283ce43..c9097d3d 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 ea2f148d..091932f7 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,125 @@ 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));
+ assert(colorspace < ARRAY_SIZE(p->color_encoding.values));
+
+ 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 +3472,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 6b1c864c..6abf6d54 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 44898a74..f713ba35 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");
More information about the xorg-commit
mailing list