From a23d61c26bea07f54f8f442c26f14decfef98203 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Sun, 24 May 2020 16:42:41 +0300 Subject: [PATCH] genesys: Allow pipeline to be created without mutating device --- backend/genesys/gl124.cpp | 2 +- backend/genesys/gl646.cpp | 2 +- backend/genesys/gl841.cpp | 2 +- backend/genesys/gl842.cpp | 2 +- backend/genesys/gl843.cpp | 2 +- backend/genesys/gl846.cpp | 2 +- backend/genesys/gl847.cpp | 2 +- backend/genesys/image_pipeline.h | 2 + backend/genesys/low.cpp | 143 ++++++++++++++----------------- backend/genesys/low.h | 6 +- 10 files changed, 80 insertions(+), 85 deletions(-) diff --git a/backend/genesys/gl124.cpp b/backend/genesys/gl124.cpp index 3a7e4faa1..fc2b24586 100644 --- a/backend/genesys/gl124.cpp +++ b/backend/genesys/gl124.cpp @@ -722,7 +722,7 @@ static void gl124_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens dev->line_count = 0; - build_image_pipeline(dev, session); + setup_image_pipeline(*dev, session); // MAXWD is expressed in 2 words unit diff --git a/backend/genesys/gl646.cpp b/backend/genesys/gl646.cpp index 9cd9cbe95..c88af01dc 100644 --- a/backend/genesys/gl646.cpp +++ b/backend/genesys/gl646.cpp @@ -840,7 +840,7 @@ void CommandSetGl646::init_regs_for_scan_session(Genesys_Device* dev, const Gene // setup analog frontend gl646_set_fe(dev, sensor, AFE_SET, session.output_resolution); - build_image_pipeline(dev, session); + setup_image_pipeline(*dev, session); dev->read_active = true; diff --git a/backend/genesys/gl841.cpp b/backend/genesys/gl841.cpp index dd851100f..de302c4ab 100644 --- a/backend/genesys/gl841.cpp +++ b/backend/genesys/gl841.cpp @@ -1056,7 +1056,7 @@ dummy \ scanned lines session.params.flags); } - build_image_pipeline(dev, session); + setup_image_pipeline(*dev, session); dev->read_active = true; diff --git a/backend/genesys/gl842.cpp b/backend/genesys/gl842.cpp index 469025a87..20e9b3737 100644 --- a/backend/genesys/gl842.cpp +++ b/backend/genesys/gl842.cpp @@ -521,7 +521,7 @@ void CommandSetGl842::init_regs_for_scan_session(Genesys_Device* dev, const Gene session.optical_line_count, dummy, session.params.starty, session.params.flags); - build_image_pipeline(dev, session); + setup_image_pipeline(*dev, session); dev->read_active = true; diff --git a/backend/genesys/gl843.cpp b/backend/genesys/gl843.cpp index de57a65de..726105ff9 100644 --- a/backend/genesys/gl843.cpp +++ b/backend/genesys/gl843.cpp @@ -1054,7 +1054,7 @@ void CommandSetGl843::init_regs_for_scan_session(Genesys_Device* dev, const Gene session.optical_line_count, dummy, session.params.starty, session.params.flags); - build_image_pipeline(dev, session); + setup_image_pipeline(*dev, session); dev->read_active = true; diff --git a/backend/genesys/gl846.cpp b/backend/genesys/gl846.cpp index 7dc00ef04..42e5c38d2 100644 --- a/backend/genesys/gl846.cpp +++ b/backend/genesys/gl846.cpp @@ -646,7 +646,7 @@ static void gl846_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens reg->set16(REG_STRPIXEL, session.pixel_startx); reg->set16(REG_ENDPIXEL, session.pixel_endx); - build_image_pipeline(dev, session); + setup_image_pipeline(*dev, session); /* MAXWD is expressed in 4 words unit */ // BUG: we shouldn't multiply by channels here diff --git a/backend/genesys/gl847.cpp b/backend/genesys/gl847.cpp index 9ac8c97a7..94a71e563 100644 --- a/backend/genesys/gl847.cpp +++ b/backend/genesys/gl847.cpp @@ -524,7 +524,7 @@ static void gl847_init_optical_regs_scan(Genesys_Device* dev, const Genesys_Sens reg->set16(REG_STRPIXEL, session.pixel_startx); reg->set16(REG_ENDPIXEL, session.pixel_endx); - build_image_pipeline(dev, session); + setup_image_pipeline(*dev, session); /* MAXWD is expressed in 4 words unit */ // BUG: we shouldn't multiply by channels here diff --git a/backend/genesys/image_pipeline.h b/backend/genesys/image_pipeline.h index cd849d844..39f6398c6 100644 --- a/backend/genesys/image_pipeline.h +++ b/backend/genesys/image_pipeline.h @@ -524,6 +524,8 @@ class ImagePipelineStack { public: ImagePipelineStack() {} + ImagePipelineStack(ImagePipelineStack&&) = default; + ImagePipelineStack& operator=(ImagePipelineStack&&) = default; ~ImagePipelineStack() { clear(); } std::size_t get_input_width() const; diff --git a/backend/genesys/low.cpp b/backend/genesys/low.cpp index 43f6ebe3e..490ffe44c 100644 --- a/backend/genesys/low.cpp +++ b/backend/genesys/low.cpp @@ -926,28 +926,26 @@ void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Se debug_dump(DBG_info, s); } -void build_image_pipeline(Genesys_Device* dev, const ScanSession& session) +ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSession& session, + unsigned pipeline_index, bool log_image_data) { - static unsigned s_pipeline_index = 0; - - s_pipeline_index++; - auto format = create_pixel_format(session.params.depth, - dev->model->is_cis ? 1 : session.params.channels, - dev->model->line_mode_color_order); + dev.model->is_cis ? 1 : session.params.channels, + dev.model->line_mode_color_order); auto depth = get_pixel_format_depth(format); auto width = get_pixels_from_row_bytes(format, session.output_line_bytes_raw); - auto read_data_from_usb = [dev](std::size_t size, std::uint8_t* data) + auto read_data_from_usb = [&dev](std::size_t size, std::uint8_t* data) { - dev->interface->bulk_read_data(0x45, data, size); + dev.interface->bulk_read_data(0x45, data, size); return true; }; + auto debug_prefix = "gl_pipeline_" + std::to_string(pipeline_index); + + ImagePipelineStack pipeline; + auto lines = session.optical_line_count; - - dev->pipeline.clear(); - auto buffer_size = session.buffer_size_read; // At least GL841 requires reads to be aligned to 2 bytes and will fail on some devices on @@ -958,141 +956,132 @@ void build_image_pipeline(Genesys_Device* dev, const ScanSession& session) new ImagePipelineNodeBufferedCallableSource( width, lines, format, buffer_size, read_data_from_usb)); node->set_last_read_multiple(2); - dev->pipeline.push_first_node(std::move(node)); + pipeline.push_first_node(std::move(node)); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_0_from_usb.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_0_from_usb.tiff"); } if (session.segment_count > 1) { auto output_width = session.output_segment_pixel_group_count * session.segment_count; - dev->pipeline.push_node(output_width, dev->segment_order, + pipeline.push_node(output_width, dev.segment_order, session.conseq_pixel_dist, 1, 1); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_1_after_desegment.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_1_after_desegment.tiff"); } } if (depth == 16) { unsigned num_swaps = 0; - if (has_flag(dev->model->flags, ModelFlag::SWAP_16BIT_DATA)) { + if (has_flag(dev.model->flags, ModelFlag::SWAP_16BIT_DATA)) { num_swaps++; } #ifdef WORDS_BIGENDIAN num_swaps++; #endif if (num_swaps % 2 != 0) { - dev->pipeline.push_node(); + pipeline.push_node(); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_2_after_swap.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_2_after_swap.tiff"); } } } - if (has_flag(dev->model->flags, ModelFlag::INVERT_PIXEL_DATA)) { - dev->pipeline.push_node(); + if (has_flag(dev.model->flags, ModelFlag::INVERT_PIXEL_DATA)) { + pipeline.push_node(); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_3_after_invert.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_3_after_invert.tiff"); } } - if (dev->model->is_cis && session.params.channels == 3) { - dev->pipeline.push_node(dev->model->line_mode_color_order); + if (dev.model->is_cis && session.params.channels == 3) { + pipeline.push_node(dev.model->line_mode_color_order); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_4_after_merge_mono.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_4_after_merge_mono.tiff"); } } - if (dev->pipeline.get_output_format() == PixelFormat::BGR888) { - dev->pipeline.push_node(PixelFormat::RGB888); + if (pipeline.get_output_format() == PixelFormat::BGR888) { + pipeline.push_node(PixelFormat::RGB888); } - if (dev->pipeline.get_output_format() == PixelFormat::BGR161616) { - dev->pipeline.push_node(PixelFormat::RGB161616); + if (pipeline.get_output_format() == PixelFormat::BGR161616) { + pipeline.push_node(PixelFormat::RGB161616); } - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_5_after_format.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_5_after_format.tiff"); } if (session.max_color_shift_lines > 0 && session.params.channels == 3) { - dev->pipeline.push_node( + pipeline.push_node( session.color_shift_lines_r, session.color_shift_lines_g, session.color_shift_lines_b); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_6_after_color_unshift.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_6_after_color_unshift.tiff"); } } if (!session.stagger_x.empty()) { // FIXME: the image will be scaled to requested pixel count without regard to the reduction // of image size in this step. - dev->pipeline.push_node(session.stagger_x.shifts()); + pipeline.push_node(session.stagger_x.shifts()); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_7_after_x_unstagger.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_7_after_x_unstagger.tiff"); } } if (session.num_staggered_lines > 0) { - dev->pipeline.push_node(session.stagger_y.shifts()); + pipeline.push_node(session.stagger_y.shifts()); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_8_after_y_unstagger.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_8_after_y_unstagger.tiff"); } } if (session.use_host_side_calib && - !has_flag(dev->model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION) && + !has_flag(dev.model->flags, ModelFlag::DISABLE_SHADING_CALIBRATION) && !has_flag(session.params.flags, ScanFlag::DISABLE_SHADING)) { - dev->pipeline.push_node(dev->dark_average_data, - dev->white_average_data, + pipeline.push_node(dev.dark_average_data, + dev.white_average_data, session.params.startx * - dev->calib_session.params.channels); + dev.calib_session.params.channels); - if (dbg_log_image_data()) { - dev->pipeline.push_node("gl_pipeline_" + - std::to_string(s_pipeline_index) + - "_9_after_calibrate.tiff"); + if (log_image_data) { + pipeline.push_node(debug_prefix + "_9_after_calibrate.tiff"); } } - if (dev->pipeline.get_output_width() != session.params.get_requested_pixels()) { - dev->pipeline.push_node(session.params.get_requested_pixels()); + if (pipeline.get_output_width() != session.params.get_requested_pixels()) { + pipeline.push_node(session.params.get_requested_pixels()); } - auto read_from_pipeline = [dev](std::size_t size, std::uint8_t* out_data) + return pipeline; +} + +void setup_image_pipeline(Genesys_Device& dev, const ScanSession& session) +{ + static unsigned s_pipeline_index = 0; + + s_pipeline_index++; + + dev.pipeline = build_image_pipeline(dev, session, s_pipeline_index, dbg_log_image_data()); + + auto read_from_pipeline = [&dev](std::size_t size, std::uint8_t* out_data) { - (void) size; // will be always equal to dev->pipeline.get_output_row_bytes() - return dev->pipeline.get_next_row_data(out_data); + (void) size; // will be always equal to dev.pipeline.get_output_row_bytes() + return dev.pipeline.get_next_row_data(out_data); }; - dev->pipeline_buffer = ImageBuffer{dev->pipeline.get_output_row_bytes(), + dev.pipeline_buffer = ImageBuffer{dev.pipeline.get_output_row_bytes(), read_from_pipeline}; } diff --git a/backend/genesys/low.h b/backend/genesys/low.h index e7d5d650c..2cb3aaf7e 100644 --- a/backend/genesys/low.h +++ b/backend/genesys/low.h @@ -418,7 +418,11 @@ extern void sanei_genesys_generate_gamma_buffer(Genesys_Device* dev, void compute_session(const Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor); -void build_image_pipeline(Genesys_Device* dev, const ScanSession& session); +ImagePipelineStack build_image_pipeline(const Genesys_Device& dev, const ScanSession& session, + unsigned pipeline_index, bool log_image_data); + +// sets up a image pipeline for device `dev` +void setup_image_pipeline(Genesys_Device& dev, const ScanSession& session); std::uint8_t compute_frontend_gain(float value, float target_value, FrontendType frontend_type);