summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-10-08 13:16:07 +0200
committerKeith Packard <keithp@keithp.com>2014-10-08 13:21:18 +0200
commitf429a517684e8f99c15bc2858e62bbd112331456 (patch)
tree648331734b98ff859364b3d7cf2452683283894c
parent527d83dde0cb78cbfbb67d203d073e41e110d4a1 (diff)
keystone: Report matrix error. Deal with "primary" in xrandr output
Compute the error cause by the fixed point matrix representation and display that. Accept the 'primary' word found in xrandr output and ignore it. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--keystone.5c116
1 files changed, 101 insertions, 15 deletions
diff --git a/keystone.5c b/keystone.5c
index a292931..f73aa8b 100644
--- a/keystone.5c
+++ b/keystone.5c
@@ -354,16 +354,17 @@ rescale (m_t m, real limit)
string
m_print (m_t m)
{
- /*
+
return sprintf ("%.8f,%.8f,%.8f,%.8f,%.8f,%.8f,%.8f,%.8f,%.8f",
m[0,0],m[0,1],m[0,2],
m[1,0],m[1,1],m[1,2],
m[2,0],m[2,1],m[2,2]);
- */
+/*
return sprintf ("%v,%v,%v,%v,%v,%v,%v,%v,%v",
m[0,0],m[0,1],m[0,2],
m[1,0],m[1,1],m[1,2],
m[2,0],m[2,1],m[2,2]);
+*/
}
int
@@ -372,6 +373,33 @@ fixed (real x)
return floor (x * 65536 + 0.5) & 0xffffffff;
}
+m_t
+to_fixed(m_t m)
+{
+ m_t r;
+
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++)
+ r[i,j] = floor(m[i,j] * 65536 + 0.5) / 65536;
+ return r;
+}
+
+m_t
+error(m_t r, m_t f)
+{
+ m_t e;
+
+ for (int i = 0; i < 3; i++)
+ for (int j = 0; j < 3; j++) {
+ real diff = abs(r[i,j] - f[i,j]);
+ if (r[i,j] != 0)
+ e[i,j] = diff / abs(r[i,j]);
+ else
+ e[i,j] = 0;
+ }
+ return e;
+}
+
void
m_print_fix (m_t m)
{
@@ -382,6 +410,55 @@ m_print_fix (m_t m)
}
}
+real[2]
+map(m_t m, real x, real y)
+{
+ real[3] in = { x, y, 1 };
+ real[3] out = { 0 ... };
+
+ for (int i = 0; i < 3; i++) {
+ for (int j = 0; j < 3; j++)
+ out[i] += m[i,j] * in[j];
+ }
+ return (real[2]) { out[0] / out[2], out[1]/ out[2] };
+}
+
+real
+position_error(m_t r, m_t f, real x, real y)
+{
+ real[2] p_r = map(r, x, y);
+ real[2] p_f = map(f, x, y);
+ real error;
+
+ error = sqrt((p_r[0] - p_f[0]) ** 2 + (p_r[1] - p_f[1]) ** 2);
+ printf ("x: %g y: %g error %g\n", x, y, error);
+ printf ("\treal x: %g y: %g\n", p_r[0], p_r[1]);
+ printf ("\tfix x: %g y: %g\n", p_f[0], p_f[1]);
+ return error;
+}
+
+real
+max_error(m_t r, m_t f) {
+ real max = 0, max_x = 0, max_y = 0;
+
+ for (int x = 0; x <= 2560; x += 2560)
+ for (int y = 0; y <= 1600; y += 1600) {
+ real error = position_error(r, f, x, y);
+ if (error > max) {
+ max = error;
+ max_x = x;
+ max_y = y;
+ }
+ }
+ printf ("max error %g at %d, %d\n", max, max_x, max_y);
+ real[2] p_r = map(r, max_x ,max_y);
+ real[2] p_f = map(f, max_x, max_y);
+ printf ("\tdesired %7.2f, %7.2f actual %7.2f, %7.2f\n",
+ p_r[0], p_r[1],
+ p_f[0], p_f[1]);
+ return max;
+}
+
string
m_row (m_t m, int row)
{
@@ -414,18 +491,22 @@ output_t[*] get_outputs () {
{
while (!File::end (randr)) {
string[*] words = String::wordsplit (File::fgets (randr), " ");
- if (dim (words) >= 3 && words[1] == "connected" &&
- File::sscanf (words[2], "%dx%d+%d+%d",
- &(int width), &(int height),
- &(int x), &(int y)) == 4)
- {
- outputs[dim(outputs)] = (output_t) {
- name = words[0],
- geometry = {
- x = x, y = y, width = width, height = height
- }
- };
- }
+ if (dim (words) >= 3 && words[1] == "connected") {
+ int geom = 2;
+ if (words[geom] == "primary")
+ geom++;
+ if (File::sscanf (words[geom], "%dx%d+%d+%d",
+ &(int width), &(int height),
+ &(int x), &(int y)) == 4)
+ {
+ outputs[dim(outputs)] = (output_t) {
+ name = words[0],
+ geometry = {
+ x = x, y = y, width = width, height = height
+ }
+ };
+ }
+ }
}
}
return outputs;
@@ -433,7 +514,7 @@ output_t[*] get_outputs () {
void main ()
{
- m_t m = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }, m_i, m_r;
+ m_t m = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }, m_i, m_r, m_f, m_e;
bool m_available = true;
output_t[*] outputs = get_outputs ();
output_t target_output;
@@ -529,8 +610,13 @@ void main ()
printf ("normal: %s\n", m_print (m));
printf ("inverse: %s\n", m_print (m_i));
printf ("scaled: %s\n", m_print (m_r));
+ m_f = to_fixed(m_r);
+ printf ("round: %s\n", m_print(m_f));
printf ("fixed:\n");
m_print_fix (m_i);
+ m_e = error(m_r, m_f);
+ printf ("error: %s\n", m_print (m_e));
+ max_error(m_r, m_f);
}
}