EDID parsing should probably be moved out of compositor-drm since other backends can provide EDIDs too.
On Thu, May 2, 2013 at 10:38 PM, Richard Hughes <hughsi...@gmail.com> wrote: > This code was originally written by Soren Sandmann <sandm...@redhat.com> > and was > found here: http://people.gnome.org/~ssp/randr/edid-parse.c > > The code has been in use in gnome-settings-daemon for a couple of years > now and > is used to generate an Auto-EDID ICC profile if the screen has not been > profiled > with a calibration device. > > This will be used by the CMS plugins in the future, and so it makes sense > being > common code in compositor-drm. > --- > src/compositor-drm.c | 56 > ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 56 insertions(+) > > diff --git a/src/compositor-drm.c b/src/compositor-drm.c > index f39096e..e4a1919 100644 > --- a/src/compositor-drm.c > +++ b/src/compositor-drm.c > @@ -136,11 +136,22 @@ struct drm_fb { > void *map; > }; > > +struct drm_color_Yxy { > + double Y; > + double x; > + double y; > +}; > + > struct drm_edid { > char eisa_id[13]; > char monitor_name[13]; > char pnp_id[5]; > char serial_number[13]; > + struct drm_color_Yxy whitepoint; > + struct drm_color_Yxy primary_red; > + struct drm_color_Yxy primary_green; > + struct drm_color_Yxy primary_blue; > + double gamma; > }; > > struct drm_output { > @@ -1558,6 +1569,31 @@ edid_parse_string(const uint8_t *data, char text[]) > #define EDID_OFFSET_SERIAL 0x0c > > static int > +edid_get_bit(int in, int bit) > +{ > + return (in & (1 << bit)) >> bit; > +} > + > +static int > +edid_get_bits(int in, int begin, int end) > +{ > + int mask = (1 << (end - begin + 1)) - 1; > + return (in >> begin) & mask; > +} > + > +static double > +edid_decode_fraction(int high, int low) > +{ > + double result = 0.0; > + int i; > + > + high = (high << 2) | low; > + for (i = 0; i < 10; ++i) > + result += edid_get_bit(high, i) * pow(2, i - 10); > + return result; > +} > + > +static int > edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length) > { > int i; > @@ -1579,6 +1615,26 @@ edid_parse(struct drm_edid *edid, const uint8_t > *data, size_t length) > edid->pnp_id[2] = 'A' + (data[EDID_OFFSET_PNPID + 1] & 0x1f) - 1; > edid->pnp_id[3] = '\0'; > > + /* get native gamma */ > + if (data[0x17] == 0xff) > + edid->gamma = -1.0; > + else > + edid->gamma = (data[0x17] + 100.0) / 100.0; > + > + /* get primaries and whitepoint */ > + edid->primary_red.Y = 1.0f; > + edid->primary_red.x = edid_decode_fraction(data[0x1b], > edid_get_bits(data[0x19], 6, 7)); > + edid->primary_red.y = edid_decode_fraction(data[0x1c], > edid_get_bits(data[0x19], 5, 4)); > + edid->primary_green.Y = 1.0f; > + edid->primary_green.x = edid_decode_fraction(data[0x1d], > edid_get_bits(data[0x19], 2, 3)); > + edid->primary_green.y = edid_decode_fraction(data[0x1e], > edid_get_bits(data[0x19], 0, 1)); > + edid->primary_blue.Y = 1.0f; > + edid->primary_blue.x = edid_decode_fraction(data[0x1f], > edid_get_bits(data[0x1a], 6, 7)); > + edid->primary_blue.y = edid_decode_fraction(data[0x20], > edid_get_bits(data[0x1a], 4, 5)); > + edid->whitepoint.Y = 1.0f; > + edid->whitepoint.x = edid_decode_fraction(data[0x21], > edid_get_bits(data[0x1a], 2, 3)); > + edid->whitepoint.y = edid_decode_fraction(data[0x22], > edid_get_bits(data[0x1a], 0, 1)); > + > /* maybe there isn't a ASCII serial number descriptor, so use this > instead */ > serial_number = (uint32_t) data[EDID_OFFSET_SERIAL + 0]; > serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 1] * 0x100; > -- > 1.8.2.1 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel >
_______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel