From 8a866b051a7a6826c456d2cb91a7fd557cb2fd35 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Wed, 13 Jul 2016 02:32:08 +0200 Subject: Applying filters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/output.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/output.h | 11 +++++++- src/ramps.c | 44 +++++++++++++++++++++++++++++ src/ramps.h | 14 ++++++++++ src/server.c | 19 ++++++++++++- 5 files changed, 175 insertions(+), 4 deletions(-) diff --git a/src/output.c b/src/output.c index b2085db..25a332a 100644 --- a/src/output.c +++ b/src/output.c @@ -23,6 +23,13 @@ +/** + * The name of the process + */ +extern char* argv0; + + + /** * Free all resources allocated to an output. * The allocation of `output` itself is not freed, @@ -310,7 +317,7 @@ ssize_t add_filter(struct output* out, struct filter* filter) /** * Recalculate the resulting gamma and - * update push the new gamam ramps to the CRTC + * update push the new gamma ramps to the CRTC * * @param output The output * @param first_updated The index of the first added or removed filter @@ -318,7 +325,87 @@ ssize_t add_filter(struct output* out, struct filter* filter) */ int flush_filters(struct output* output, size_t first_updated) { - /* TODO */ (void) output, (void) first_updated; + union gamma_ramps plain; + union gamma_ramps* last; + size_t i; + int r = 0; + + if (first_updated == 0) + { + if (make_plain_ramps(&plain, output) < 0) + return -1; + last = &plain; + } + else + last = output->table_sums + (first_updated - 1); + + for (i = first_updated; i < output->table_size; i++) + { + apply(output->table_sums + i, output->table_filters[i].ramps, output->depth, last); + last = output->table_sums + i; + } + + switch (output->depth) + { + case 8: r = libgamma_crtc_set_gamma_ramps8(output->crtc, last->u8); break; + case 16: r = libgamma_crtc_set_gamma_ramps16(output->crtc, last->u16); break; + case 32: r = libgamma_crtc_set_gamma_ramps32(output->crtc, last->u32); break; + case 64: r = libgamma_crtc_set_gamma_ramps64(output->crtc, last->u64); break; + case -1: r = libgamma_crtc_set_gamma_rampsf(output->crtc, last->f); break; + case -2: r = libgamma_crtc_set_gamma_rampsd(output->crtc, last->d); break; + default: + abort(); + } + if (r) + libgamma_perror(argv0, r); /* Not fatal */ + + if (first_updated == 0) + libgamma_gamma_ramps8_destroy(&(plain.u8)); + + return 0; +} + + +/** + * Make identity mapping ramps + * + * @param ramps Output parameter for the ramps + * @param output The output for which the ramps shall be configured + * @return Zero on success, -1 on error + */ +int make_plain_ramps(union gamma_ramps* ramps, struct output* output) +{ + COPY_RAMP_SIZES(&(ramps->u8), output); + switch (output->depth) + { + case 8: + if (libgamma_gamma_ramps8_initialise(&(ramps->u8))) + return -1; + break; + case 16: + if (libgamma_gamma_ramps16_initialise(&(ramps->u16))) + return -1; + break; + case 32: + if (libgamma_gamma_ramps32_initialise(&(ramps->u32))) + return -1; + break; + case 64: + if (libgamma_gamma_ramps64_initialise(&(ramps->u64))) + return -1; + break; + case -1: + if (libgamma_gamma_rampsf_initialise(&(ramps->f))) + return -1; + break; + case -2: + if (libgamma_gamma_rampsd_initialise(&(ramps->d))) + return -1; + break; + default: + abort(); + } + /* TODO fill ramps (use libclut) */ return 0; } diff --git a/src/output.h b/src/output.h index 8d59eec..a75ebfa 100644 --- a/src/output.h +++ b/src/output.h @@ -199,7 +199,7 @@ ssize_t add_filter(struct output* output, struct filter* filter); /** * Recalculate the resulting gamma and - * update push the new gamam ramps to the CRTC + * update push the new gamma ramps to the CRTC * * @param output The output * @param first_updated The index of the first added or removed filter @@ -207,3 +207,12 @@ ssize_t add_filter(struct output* output, struct filter* filter); */ int flush_filters(struct output* output, size_t first_updated); +/** + * Make identity mapping ramps + * + * @param ramps Output parameter for the ramps + * @param output The output for which the ramps shall be configured + * @return Zero on success, -1 on error + */ +int make_plain_ramps(union gamma_ramps* ramps, struct output* output); + diff --git a/src/ramps.c b/src/ramps.c index b7ad978..d8d4975 100644 --- a/src/ramps.c +++ b/src/ramps.c @@ -94,3 +94,47 @@ size_t gamma_ramps_unmarshal(union gamma_ramps* this, const void* buf, size_t ra return ramps_size; } + +/** + * Apply a ramp-trio on top of another ramp-trio + * + * @param dest The output for the resulting ramp-trio, must be initialised + * @param application The red, green and blue ramps, as one single raw array, + * of the filter that should be applied + * @param depth -1: `float` stops + * -2: `double` stops + * Other: the number of bits of each (integral) stop + * @param base The CLUT on top of which the new filter should be applied, + * this can be the same pointer as `dest` + */ +void apply(union gamma_ramps* dest, void* application, int depth, union gamma_ramps* base) +{ + union gamma_ramps app; + size_t bytedepth; + size_t red_width, green_width, blue_width; + + if (depth == -1) + bytedepth = sizeof(float); + else if (depth == -2) + bytedepth = sizeof(double); + else + bytedepth = (size_t)depth / 8; + + red_width = (app.u8.red_size = base->u8.red_size) * bytedepth; + green_width = (app.u8.green_size = base->u8.green_size) * bytedepth; + blue_width = (app.u8.blue_size = base->u8.blue_size) * bytedepth; + + app.u8.red = application; + app.u8.green = app.u8.red + red_width; + app.u8.blue = app.u8.green + green_width; + + if (dest != base) + { + memcpy(dest->u8.red, base->u8.red, red_width); + memcpy(dest->u8.green, base->u8.green, green_width); + memcpy(dest->u8.blue, base->u8.blue, blue_width); + } + + /* TODO apply with libclut */ +} + diff --git a/src/ramps.h b/src/ramps.h index 8261a61..d2b769f 100644 --- a/src/ramps.h +++ b/src/ramps.h @@ -81,3 +81,17 @@ size_t gamma_ramps_marshal(const union gamma_ramps* this, void* buf, size_t ramp */ size_t gamma_ramps_unmarshal(union gamma_ramps* this, const void* buf, size_t ramps_size); +/** + * Apply a ramp-trio on top of another ramp-trio + * + * @param dest The output for the resulting ramp-trio, must be initialised + * @param application The red, green and blue ramps, as one single raw array, + * of the filter that should be applied + * @param depth -1: `float` stops + * -2: `double` stops + * Other: the number of bits of each (integral) stop + * @param base The CLUT on top of which the new filter should be applied, + * this can be the same pointer as `dest` + */ +void apply(union gamma_ramps* dest, void* application, int depth, union gamma_ramps* base); + diff --git a/src/server.c b/src/server.c index d046a95..06d88da 100644 --- a/src/server.c +++ b/src/server.c @@ -603,7 +603,24 @@ static int get_gamma(size_t conn, char* message_id, char* crtc, char* coalesce, n = (size_t)m; if (coal) { - /* TODO coalesce */ + if (start == 0) + memcpy(buf + n, output->table_sums[end].u8.red, output->ramps_size); + else + { + union gamma_ramps ramps; + if (make_plain_ramps(&ramps, output)) + { + int saved_errno = errno; + free(buf); + errno = saved_errno; + return -1; + } + for (i = start; i < end; i++) + apply(&ramps, output->table_filters[i].ramps, output->depth, &ramps); + memcpy(buf + n, ramps.u8.red, output->ramps_size); + libgamma_gamma_ramps8_destroy(&(ramps.u8)); + } + n += output->ramps_size; } else for (i = start; i < end; i++) -- cgit v1.2.3-70-g09d2