From a0cead1cd5d43bba44fc400676ee52b86fc8c186 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 12 Sep 2019 20:28:45 +0300 Subject: [PATCH 1/2] genesys: Pass asic type to sanei_genesys_get_bulk_max_size() --- backend/genesys_gl841.cc | 4 ++-- backend/genesys_low.cc | 14 +++++++------- backend/genesys_low.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/backend/genesys_gl841.cc b/backend/genesys_gl841.cc index 66c064d6a..2de6ac866 100644 --- a/backend/genesys_gl841.cc +++ b/backend/genesys_gl841.cc @@ -1883,8 +1883,8 @@ dummy \ scanned lines requested_buffer_size = 8 * session.output_line_bytes; // we must use a multiple of session.output_line_bytes - if (requested_buffer_size > sanei_genesys_get_bulk_max_size(dev)) { - requested_buffer_size = (sanei_genesys_get_bulk_max_size(dev) / session.output_line_bytes) * session.output_line_bytes; + if (requested_buffer_size > sanei_genesys_get_bulk_max_size(dev->model->asic_type)) { + requested_buffer_size = (sanei_genesys_get_bulk_max_size(dev->model->asic_type) / session.output_line_bytes) * session.output_line_bytes; } read_buffer_size = 2 * requested_buffer_size + diff --git a/backend/genesys_low.cc b/backend/genesys_low.cc index 6bb2b5664..15c26a2f4 100644 --- a/backend/genesys_low.cc +++ b/backend/genesys_low.cc @@ -183,7 +183,7 @@ void sanei_genesys_write_pnm_file16(const char* filename, uint16_t* data, unsign /* Read and write RAM, registers and AFE */ /* ------------------------------------------------------------------------ */ -extern unsigned sanei_genesys_get_bulk_max_size(Genesys_Device * dev) +unsigned sanei_genesys_get_bulk_max_size(AsicType asic_type) { /* Genesys supports 0xFE00 maximum size in general, wheraus GL646 supports 0xFFC0. We use 0xF000 because that's the packet limit in the Linux usbmon @@ -191,9 +191,9 @@ extern unsigned sanei_genesys_get_bulk_max_size(Genesys_Device * dev) b_size is the size of the ring buffer. By default it's 300*1024, so the packet is limited 61440 without any visibility to acquiring software. */ - if (dev->model->asic_type == AsicType::GL124 || - dev->model->asic_type == AsicType::GL846 || - dev->model->asic_type == AsicType::GL847) + if (asic_type == AsicType::GL124 || + asic_type == AsicType::GL846 || + asic_type == AsicType::GL847) { return 0xeff0; } @@ -273,7 +273,7 @@ void sanei_genesys_bulk_read_data(Genesys_Device * dev, uint8_t addr, uint8_t* d target = len; buffer = data; - size_t max_in_size = sanei_genesys_get_bulk_max_size(dev); + size_t max_in_size = sanei_genesys_get_bulk_max_size(dev->model->asic_type); if (!has_header_before_each_chunk) { sanei_genesys_bulk_read_data_send_header(dev, len); @@ -318,7 +318,7 @@ void sanei_genesys_bulk_write_data(Genesys_Device* dev, uint8_t addr, uint8_t* d dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX, 1, &addr); - size_t max_out_size = sanei_genesys_get_bulk_max_size(dev); + size_t max_out_size = sanei_genesys_get_bulk_max_size(dev->model->asic_type); while (len) { if (len > max_out_size) @@ -981,7 +981,7 @@ void sanei_genesys_write_ahb(Genesys_Device* dev, uint32_t addr, uint32_t size, // write addr and size for AHB dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x01, 8, outdata); - size_t max_out_size = sanei_genesys_get_bulk_max_size(dev); + size_t max_out_size = sanei_genesys_get_bulk_max_size(dev->model->asic_type); /* write actual data */ written = 0; diff --git a/backend/genesys_low.h b/backend/genesys_low.h index d45b16e0f..46d1cdd57 100644 --- a/backend/genesys_low.h +++ b/backend/genesys_low.h @@ -408,7 +408,7 @@ extern void sanei_genesys_bulk_write_register(Genesys_Device* dev, extern void sanei_genesys_write_0x8c(Genesys_Device* dev, uint8_t index, uint8_t val); -extern unsigned sanei_genesys_get_bulk_max_size(Genesys_Device * dev); +unsigned sanei_genesys_get_bulk_max_size(AsicType asic_type); extern void sanei_genesys_bulk_read_data(Genesys_Device * dev, uint8_t addr, uint8_t* data, size_t len); From cbb7e953505e09f049e142f8cf30d903fb1d1d50 Mon Sep 17 00:00:00 2001 From: Povilas Kanapickas Date: Thu, 12 Sep 2019 20:28:46 +0300 Subject: [PATCH 2/2] genesys: Use common code path to compute session buffer sizes --- backend/genesys_gl124.cc | 17 +++------- backend/genesys_gl646.cc | 17 +++------- backend/genesys_gl841.cc | 22 +++---------- backend/genesys_gl843.cc | 19 +++-------- backend/genesys_gl846.cc | 14 +++------ backend/genesys_gl847.cc | 16 +++------- backend/genesys_low.cc | 64 ++++++++++++++++++++++++++++++++++++-- backend/genesys_settings.h | 9 ++++-- 8 files changed, 92 insertions(+), 86 deletions(-) diff --git a/backend/genesys_gl124.cc b/backend/genesys_gl124.cc index 7ee17af70..2f28a021f 100644 --- a/backend/genesys_gl124.cc +++ b/backend/genesys_gl124.cc @@ -1058,7 +1058,6 @@ static void gl124_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens int dummy = 0; int slope_dpi = 0; int scan_step_type = 1; - size_t requested_buffer_size, read_buffer_size; DBG (DBG_info, "%s: optical_res=%d\n", __func__, session.optical_resolution); @@ -1125,25 +1124,17 @@ static void gl124_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens /*** prepares data reordering ***/ - /* since we don't have sheetfed scanners to handle, - * use huge read buffer */ - /* TODO find the best size according to settings */ - requested_buffer_size = 16 * session.output_line_bytes; - - read_buffer_size = 2 * requested_buffer_size + - (session.max_color_shift_lines + session.num_staggered_lines) * session.optical_line_bytes; - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); + dev->read_buffer.alloc(session.buffer_size_read); dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); + dev->lines_buffer.alloc(session.buffer_size_lines); dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); + dev->shrink_buffer.alloc(session.buffer_size_shrink); dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * dev->settings.pixels * session.params.channels * session.params.depth) / 8); + dev->out_buffer.alloc(session.buffer_size_out); dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count; diff --git a/backend/genesys_gl646.cc b/backend/genesys_gl646.cc index 4a9a01879..8cbb807c6 100644 --- a/backend/genesys_gl646.cc +++ b/backend/genesys_gl646.cc @@ -359,7 +359,6 @@ static void gl646_setup_registers(Genesys_Device* dev, unsigned int used1, used2, vfinal; uint32_t z1, z2; uint16_t ex, sx; - size_t read_buffer_size; int feedl; DBG(DBG_info, "%s: startx=%d, endx=%d\n", __func__, startx, endx); @@ -719,25 +718,17 @@ static void gl646_setup_registers(Genesys_Device* dev, // setup analog frontend gl646_set_fe(dev, sensor, AFE_SET, session.output_resolution); - /* now we're done with registers setup values used by data transfer */ - /* we setup values needed for the data transfer */ - - // we must use a round number of words_per_line - read_buffer_size = 16 * session.output_line_bytes + - ((session.max_color_shift_lines + session.num_staggered_lines) * session.params.pixels * - session.params.channels * session.params.depth) / 8; - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); + dev->read_buffer.alloc(session.buffer_size_read); dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); + dev->lines_buffer.alloc(session.buffer_size_lines); dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(8 * session.output_line_bytes); + dev->shrink_buffer.alloc(session.buffer_size_shrink); dev->out_buffer.clear(); - dev->out_buffer.alloc(8 * session.output_line_bytes); + dev->out_buffer.alloc(session.buffer_size_out); /* scan bytes to read */ unsigned cis_channel_multiplier = dev->model->is_cis ? session.params.channels : 1; diff --git a/backend/genesys_gl841.cc b/backend/genesys_gl841.cc index 2de6ac866..d9e59cc41 100644 --- a/backend/genesys_gl841.cc +++ b/backend/genesys_gl841.cc @@ -1735,7 +1735,6 @@ static void gl841_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens int slope_dpi = 0; int dummy = 0; int scan_step_type = 1; - size_t requested_buffer_size, read_buffer_size; /* results: @@ -1877,30 +1876,17 @@ dummy \ scanned lines MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE : 0); } - - - /*** prepares data reordering ***/ - - requested_buffer_size = 8 * session.output_line_bytes; - // we must use a multiple of session.output_line_bytes - if (requested_buffer_size > sanei_genesys_get_bulk_max_size(dev->model->asic_type)) { - requested_buffer_size = (sanei_genesys_get_bulk_max_size(dev->model->asic_type) / session.output_line_bytes) * session.output_line_bytes; - } - - read_buffer_size = 2 * requested_buffer_size + - (session.max_color_shift_lines + session.num_staggered_lines) * session.optical_line_bytes; - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); + dev->read_buffer.alloc(session.buffer_size_read); dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); + dev->lines_buffer.alloc(session.buffer_size_lines); dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); + dev->shrink_buffer.alloc(session.buffer_size_shrink); dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * dev->settings.pixels * session.params.channels * session.params.depth) / 8); + dev->out_buffer.alloc(session.buffer_size_out); dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count; diff --git a/backend/genesys_gl843.cc b/backend/genesys_gl843.cc index 1bd6c1c66..c187356cb 100644 --- a/backend/genesys_gl843.cc +++ b/backend/genesys_gl843.cc @@ -1222,7 +1222,6 @@ static void gl843_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens int slope_dpi = 0; int dummy = 0; int scan_step_type = 1; - size_t requested_buffer_size, read_buffer_size; DBG(DBG_info, "%s : stagger=%d lines\n", __func__, session.num_staggered_lines); @@ -1300,27 +1299,17 @@ static void gl843_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens gl843_init_motor_regs_scan(dev, sensor, reg, exposure, slope_dpi, scan_step_type, scan_lines, dummy, session.params.starty, mflags); - /* since we don't have sheetfed scanners to handle, - * use huge read buffer */ - /* TODO find the best size according to settings */ - requested_buffer_size = 16 * session.output_line_bytes; - - read_buffer_size = - 2 * requested_buffer_size + - (session.max_color_shift_lines + session.num_staggered_lines) * session.optical_line_bytes; - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); + dev->read_buffer.alloc(session.buffer_size_read); dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); + dev->lines_buffer.alloc(session.buffer_size_lines); dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); + dev->shrink_buffer.alloc(session.buffer_size_shrink); dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * session.params.pixels * session.params.channels * - session.params.depth) / 8); + dev->out_buffer.alloc(session.buffer_size_out); dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count; diff --git a/backend/genesys_gl846.cc b/backend/genesys_gl846.cc index d553d1454..bd4723c62 100644 --- a/backend/genesys_gl846.cc +++ b/backend/genesys_gl846.cc @@ -944,7 +944,6 @@ static void gl846_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens int slope_dpi = 0; int dummy = 0; int scan_step_type = 1; - size_t requested_buffer_size, read_buffer_size; /* compute scan parameters values */ /* pixels are allways given at full optical resolution */ @@ -1010,22 +1009,17 @@ static void gl846_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens /*** prepares data reordering ***/ - requested_buffer_size = 8 * session.output_line_bytes; - - read_buffer_size = 2 * requested_buffer_size + - (session.max_color_shift_lines + session.num_staggered_lines) * session.optical_line_bytes; - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); + dev->read_buffer.alloc(session.buffer_size_read); dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); + dev->lines_buffer.alloc(session.buffer_size_lines); dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); + dev->shrink_buffer.alloc(session.buffer_size_shrink); dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * session.params.pixels * session.params.channels * session.params.depth) / 8); + dev->out_buffer.alloc(session.buffer_size_out); dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count; diff --git a/backend/genesys_gl847.cc b/backend/genesys_gl847.cc index cc463ae7a..3a45afa85 100644 --- a/backend/genesys_gl847.cc +++ b/backend/genesys_gl847.cc @@ -961,7 +961,6 @@ static void gl847_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens int slope_dpi = 0; int dummy = 0; int scan_step_type = 1; - size_t requested_buffer_size, read_buffer_size; /* compute scan parameters values */ /* pixels are allways given at full optical resolution */ @@ -1022,24 +1021,17 @@ static void gl847_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens : session.output_line_count, dummy, move, mflags); - /*** prepares data reordering ***/ - - requested_buffer_size = 8 * session.output_line_bytes; - - read_buffer_size = 2 * requested_buffer_size + - (session.max_color_shift_lines + session.num_staggered_lines) * session.optical_line_bytes; - dev->read_buffer.clear(); - dev->read_buffer.alloc(read_buffer_size); + dev->read_buffer.alloc(session.buffer_size_read); dev->lines_buffer.clear(); - dev->lines_buffer.alloc(read_buffer_size); + dev->lines_buffer.alloc(session.buffer_size_lines); dev->shrink_buffer.clear(); - dev->shrink_buffer.alloc(requested_buffer_size); + dev->shrink_buffer.alloc(session.buffer_size_shrink); dev->out_buffer.clear(); - dev->out_buffer.alloc((8 * session.params.pixels * session.params.channels * session.params.depth) / 8); + dev->out_buffer.alloc(session.buffer_size_out); dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count; diff --git a/backend/genesys_low.cc b/backend/genesys_low.cc index 15c26a2f4..aa3b70215 100644 --- a/backend/genesys_low.cc +++ b/backend/genesys_low.cc @@ -1138,6 +1138,62 @@ static unsigned align_int_up(unsigned num, unsigned alignment) return num; } +void compute_session_buffer_sizes(AsicType asic, ScanSession& s) +{ + size_t line_bytes = s.output_line_bytes; + size_t line_bytes_stagger = s.output_line_bytes; + + if (asic != AsicType::GL646) { + // BUG: this is historical artifact and should be removed. Note that buffer sizes affect + // how often we request the scanner for data and thus change the USB traffic. + line_bytes_stagger = + multiply_by_depth_ceil(s.optical_pixels, s.params.depth) * s.params.channels; + } + + struct BufferConfig { + size_t* result_size = nullptr; + size_t lines = 0; + size_t lines_mult = 0; + size_t max_size = 0; // does not apply if 0 + size_t stagger_lines = 0; + }; + + std::array configs; + if (asic == AsicType::GL124 || asic == AsicType::GL843) { + configs = { { + { &s.buffer_size_read, 32, 1, 0, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_lines, 32, 1, 0, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_shrink, 16, 1, 0, 0 }, + { &s.buffer_size_out, 8, 1, 0, 0 }, + } }; + } else if (asic == AsicType::GL841) { + size_t max_buf = sanei_genesys_get_bulk_max_size(asic); + configs = { { + { &s.buffer_size_read, 8, 2, max_buf, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_lines, 8, 2, max_buf, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_shrink, 8, 1, max_buf, 0 }, + { &s.buffer_size_out, 8, 1, 0, 0 }, + } }; + } else { + configs = { { + { &s.buffer_size_read, 16, 1, 0, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_lines, 16, 1, 0, s.max_color_shift_lines + s.num_staggered_lines }, + { &s.buffer_size_shrink, 8, 1, 0, 0 }, + { &s.buffer_size_out, 8, 1, 0, 0 }, + } }; + } + + for (BufferConfig& config : configs) { + size_t buf_size = line_bytes * config.lines; + if (config.max_size > 0 && buf_size > config.max_size) { + buf_size = (config.max_size / line_bytes) * line_bytes; + } + buf_size *= config.lines_mult; + buf_size += line_bytes_stagger * config.stagger_lines; + *config.result_size = buf_size; + } +} + void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor) { DBG_HELPER(dbg); @@ -1224,9 +1280,10 @@ void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& s.output_line_count = s.params.lines + s.max_color_shift_lines + s.num_staggered_lines; - s.optical_line_bytes = multiply_by_depth_ceil(s.optical_pixels, s.params.depth) * s.params.channels; s.output_line_channel_bytes = multiply_by_depth_ceil(s.output_pixels, s.params.depth); s.output_line_bytes = s.output_line_channel_bytes * s.params.channels; + + compute_session_buffer_sizes(dev->model->asic_type, s); } /** @brief initialize device @@ -1860,7 +1917,6 @@ void debug_dump(unsigned level, const ScanSession& session) DBG(level, " ccd_size_divisor : %d\n", session.ccd_size_divisor); DBG(level, " optical_resolution : %d\n", session.optical_resolution); DBG(level, " optical_pixels : %d\n", session.optical_pixels); - DBG(level, " optical_line_bytes : %d\n", session.optical_line_bytes); DBG(level, " output_resolution : %d\n", session.output_resolution); DBG(level, " output_pixels : %d\n", session.output_pixels); DBG(level, " output_line_bytes : %d\n", session.output_line_bytes); @@ -1870,6 +1926,10 @@ void debug_dump(unsigned level, const ScanSession& session) DBG(level, " enable_ledadd : %d\n", session.enable_ledadd); DBG(level, " pixel_startx : %d\n", session.pixel_startx); DBG(level, " pixel_endx : %d\n", session.pixel_endx); + DBG(level, " buffer_size_read : %zu\n", session.buffer_size_read); + DBG(level, " buffer_size_read : %zu\n", session.buffer_size_lines); + DBG(level, " buffer_size_shrink : %zu\n", session.buffer_size_shrink); + DBG(level, " buffer_size_out : %zu\n", session.buffer_size_out); debug_dump(level, session.params); } diff --git a/backend/genesys_settings.h b/backend/genesys_settings.h index b35f80e41..ca15d6d3c 100644 --- a/backend/genesys_settings.h +++ b/backend/genesys_settings.h @@ -230,9 +230,6 @@ struct ScanSession { // the number of pixels at the optical resolution. unsigned optical_pixels = 0; - // the number of bytes in the output of a single line directly from scanner - unsigned optical_line_bytes = 0; - // the resolution of the output data. // gl843-only unsigned output_resolution = 0; @@ -263,6 +260,12 @@ struct ScanSession { unsigned pixel_startx = 0; unsigned pixel_endx = 0; + // the sizes of the corresponding buffers + size_t buffer_size_read = 0; + size_t buffer_size_lines = 0; + size_t buffer_size_shrink = 0; + size_t buffer_size_out = 0; + // whether to enable ledadd functionality bool enable_ledadd = false;