Enable 3 & 5 temporal planes
By doing a bit more math we can create a sensible schedule for these situations. A 6/3 schedule gives a very nice 150fps with temporal shimmer at 50Hz
This commit is contained in:
parent
450e3b61d3
commit
8b9f7d7006
3 changed files with 35 additions and 22 deletions
|
|
@ -27,8 +27,8 @@ class _PybindEnumChoice(click.Choice):
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def _validate_temporal_planes(ctx, param, value):
|
def _validate_temporal_planes(ctx, param, value):
|
||||||
if value not in (0, 2, 4):
|
if value not in (0, 1, 2, 3, 4, 5):
|
||||||
raise click.BadParameter("must be 0, 2, or 4")
|
raise click.BadParameter("must be from 0 to 5 (0 and 1 both disable temporal planes)")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def standard_options(
|
def standard_options(
|
||||||
|
|
|
||||||
|
|
@ -134,31 +134,26 @@ schedule_sequence make_temporal_dither_schedule(int n_planes,
|
||||||
if (n_temporal_planes >= n_planes) {
|
if (n_temporal_planes >= n_planes) {
|
||||||
throw std::range_error("n_temporal_planes can't exceed n_planes");
|
throw std::range_error("n_temporal_planes can't exceed n_planes");
|
||||||
}
|
}
|
||||||
if (n_temporal_planes != 2 && n_temporal_planes != 4) {
|
|
||||||
// the code can generate a schedule for 8 temporal planes, but it
|
|
||||||
// flickers intolerably
|
|
||||||
throw std::range_error("n_temporal_planes must be 0, 1, 2, or 4");
|
|
||||||
}
|
|
||||||
|
|
||||||
int n_real_planes = n_planes - n_temporal_planes;
|
int n_real_planes = n_planes - n_temporal_planes;
|
||||||
|
|
||||||
schedule base_sched;
|
|
||||||
for (int j = 0; j < n_real_planes; j++) {
|
|
||||||
base_sched.emplace_back(
|
|
||||||
9 - j, (1 << (n_temporal_planes + n_real_planes - j - 1)) /
|
|
||||||
n_temporal_planes);
|
|
||||||
}
|
|
||||||
|
|
||||||
schedule_sequence result;
|
schedule_sequence result;
|
||||||
|
|
||||||
auto add_sched = [&result, &base_sched](int plane, int count) {
|
auto add_sched = [&result, n_real_planes,
|
||||||
auto sched = base_sched;
|
n_temporal_planes](int i, int plane, int count) {
|
||||||
|
schedule sched;
|
||||||
|
for (int j = 0; j < n_real_planes; j++) {
|
||||||
|
int k = 1 << (n_temporal_planes + n_real_planes - j - 1);
|
||||||
|
printf("n_real_planes=%d n_temporal_planes=%d plane=%d k=%d\n",
|
||||||
|
n_real_planes, n_temporal_planes, j, k);
|
||||||
|
sched.emplace_back(9 - j, (k + i) / n_temporal_planes);
|
||||||
|
}
|
||||||
sched.emplace_back(9 - plane, count);
|
sched.emplace_back(9 - plane, count);
|
||||||
result.emplace_back(sched);
|
result.emplace_back(sched);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < n_temporal_planes; i++) {
|
for (int i = 0; i < n_temporal_planes; i++) {
|
||||||
add_sched(n_real_planes + i, 1 << (n_temporal_planes - i - 1));
|
add_sched(i, n_real_planes + i, 1 << (n_temporal_planes - i - 1));
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
std::vector<uint32_t> counts(10, 0);
|
std::vector<uint32_t> counts(10, 0);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "piomatter/piomatter.h"
|
#include "piomatter/piomatter.h"
|
||||||
|
|
@ -61,7 +62,7 @@ uint32_t pixels[height][width] = {
|
||||||
#undef w
|
#undef w
|
||||||
#undef _
|
#undef _
|
||||||
|
|
||||||
#define rgb(r, g, b) ((r << 16) | (g << 8) | b)
|
#define rgb(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
||||||
|
|
||||||
uint32_t colorwheel(int i) {
|
uint32_t colorwheel(int i) {
|
||||||
i = i & 0xff;
|
i = i & 0xff;
|
||||||
|
|
@ -102,28 +103,42 @@ static void print_dither_schedule(const piomatter::schedule_sequence &ss) {
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
printf(" -> ");
|
||||||
|
std::map<int, int> sums;
|
||||||
|
for (auto s : ss) {
|
||||||
|
for (auto i : s) {
|
||||||
|
sums[-i.shift] += i.active_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto const &i : sums) {
|
||||||
|
printf("{%d %d} ", -i.first, i.second);
|
||||||
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_simple_dither_schedule(int n_planes, int pixels_across) {
|
static void test_simple_dither_schedule(int n_planes, int pixels_across) {
|
||||||
auto ss = piomatter::make_simple_schedule(n_planes, pixels_across);
|
auto ss = piomatter::make_simple_schedule(n_planes, pixels_across);
|
||||||
print_dither_schedule(ss);
|
print_dither_schedule(ss);
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
static void test_temporal_dither_schedule(int n_planes, int pixels_across,
|
static void test_temporal_dither_schedule(int n_planes, int pixels_across,
|
||||||
int n_temporal_frames) {
|
int n_temporal_frames) {
|
||||||
auto ss = piomatter::make_temporal_dither_schedule(n_planes, pixels_across,
|
auto ss = piomatter::make_temporal_dither_schedule(n_planes, pixels_across,
|
||||||
n_temporal_frames);
|
n_temporal_frames);
|
||||||
print_dither_schedule(ss);
|
print_dither_schedule(ss);
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
int n = argc > 1 ? atoi(argv[1]) : 0;
|
int n = argc > 1 ? atoi(argv[1]) : 0;
|
||||||
|
|
||||||
test_simple_dither_schedule(5, 1);
|
test_simple_dither_schedule(7, 1);
|
||||||
test_temporal_dither_schedule(5, 1, 0);
|
test_temporal_dither_schedule(7, 1, 2);
|
||||||
test_temporal_dither_schedule(5, 1, 2);
|
test_temporal_dither_schedule(7, 1, 3);
|
||||||
test_temporal_dither_schedule(5, 1, 4);
|
test_temporal_dither_schedule(7, 1, 4);
|
||||||
|
test_temporal_dither_schedule(7, 1, 5);
|
||||||
|
|
||||||
|
return 0;
|
||||||
test_simple_dither_schedule(6, 1);
|
test_simple_dither_schedule(6, 1);
|
||||||
test_temporal_dither_schedule(6, 1, 0);
|
test_temporal_dither_schedule(6, 1, 0);
|
||||||
test_temporal_dither_schedule(6, 1, 2);
|
test_temporal_dither_schedule(6, 1, 2);
|
||||||
|
|
@ -131,6 +146,7 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
test_simple_dither_schedule(5, 16);
|
test_simple_dither_schedule(5, 16);
|
||||||
test_temporal_dither_schedule(5, 16, 2);
|
test_temporal_dither_schedule(5, 16, 2);
|
||||||
|
test_temporal_dither_schedule(5, 16, 3);
|
||||||
test_temporal_dither_schedule(5, 16, 4);
|
test_temporal_dither_schedule(5, 16, 4);
|
||||||
|
|
||||||
test_simple_dither_schedule(5, 24);
|
test_simple_dither_schedule(5, 24);
|
||||||
|
|
@ -140,6 +156,8 @@ int main(int argc, char **argv) {
|
||||||
test_simple_dither_schedule(10, 24);
|
test_simple_dither_schedule(10, 24);
|
||||||
test_temporal_dither_schedule(10, 24, 8);
|
test_temporal_dither_schedule(10, 24, 8);
|
||||||
|
|
||||||
|
test_temporal_dither_schedule(5, 128, 3);
|
||||||
|
test_temporal_dither_schedule(5, 192, 3);
|
||||||
test_temporal_dither_schedule(5, 128, 4);
|
test_temporal_dither_schedule(5, 128, 4);
|
||||||
test_temporal_dither_schedule(5, 192, 4);
|
test_temporal_dither_schedule(5, 192, 4);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue