Merge branch 'genesys-session-buffer-sizes' into 'master'

genesys: Use common code path for computing session buffer sizes

See merge request sane-project/backends!161
merge-requests/162/merge
Povilas Kanapickas 2019-09-22 20:47:19 +00:00
commit cad4085565
9 zmienionych plików z 100 dodań i 94 usunięć

Wyświetl plik

@ -1058,7 +1058,6 @@ static void gl124_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
int dummy = 0; int dummy = 0;
int slope_dpi = 0; int slope_dpi = 0;
int scan_step_type = 1; 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); 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 ***/ /*** 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.clear();
dev->read_buffer.alloc(read_buffer_size); dev->read_buffer.alloc(session.buffer_size_read);
dev->lines_buffer.clear(); 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.clear();
dev->shrink_buffer.alloc(requested_buffer_size); dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear(); 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; dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count;

Wyświetl plik

@ -359,7 +359,6 @@ static void gl646_setup_registers(Genesys_Device* dev,
unsigned int used1, used2, vfinal; unsigned int used1, used2, vfinal;
uint32_t z1, z2; uint32_t z1, z2;
uint16_t ex, sx; uint16_t ex, sx;
size_t read_buffer_size;
int feedl; int feedl;
DBG(DBG_info, "%s: startx=%d, endx=%d\n", __func__, startx, endx); 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 // setup analog frontend
gl646_set_fe(dev, sensor, AFE_SET, session.output_resolution); 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.clear();
dev->read_buffer.alloc(read_buffer_size); dev->read_buffer.alloc(session.buffer_size_read);
dev->lines_buffer.clear(); 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.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.clear();
dev->out_buffer.alloc(8 * session.output_line_bytes); dev->out_buffer.alloc(session.buffer_size_out);
/* scan bytes to read */ /* scan bytes to read */
unsigned cis_channel_multiplier = dev->model->is_cis ? session.params.channels : 1; unsigned cis_channel_multiplier = dev->model->is_cis ? session.params.channels : 1;

Wyświetl plik

@ -1735,7 +1735,6 @@ static void gl841_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
int slope_dpi = 0; int slope_dpi = 0;
int dummy = 0; int dummy = 0;
int scan_step_type = 1; int scan_step_type = 1;
size_t requested_buffer_size, read_buffer_size;
/* /*
results: results:
@ -1877,30 +1876,17 @@ dummy \ scanned lines
MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE : 0); 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)) {
requested_buffer_size = (sanei_genesys_get_bulk_max_size(dev) / 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.clear();
dev->read_buffer.alloc(read_buffer_size); dev->read_buffer.alloc(session.buffer_size_read);
dev->lines_buffer.clear(); 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.clear();
dev->shrink_buffer.alloc(requested_buffer_size); dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear(); 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; dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count;

Wyświetl plik

@ -1222,7 +1222,6 @@ static void gl843_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
int slope_dpi = 0; int slope_dpi = 0;
int dummy = 0; int dummy = 0;
int scan_step_type = 1; 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); 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, gl843_init_motor_regs_scan(dev, sensor, reg, exposure, slope_dpi, scan_step_type,
scan_lines, dummy, session.params.starty, mflags); 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.clear();
dev->read_buffer.alloc(read_buffer_size); dev->read_buffer.alloc(session.buffer_size_read);
dev->lines_buffer.clear(); 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.clear();
dev->shrink_buffer.alloc(requested_buffer_size); dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear(); dev->out_buffer.clear();
dev->out_buffer.alloc((8 * session.params.pixels * session.params.channels * dev->out_buffer.alloc(session.buffer_size_out);
session.params.depth) / 8);
dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count; dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count;

Wyświetl plik

@ -944,7 +944,6 @@ static void gl846_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
int slope_dpi = 0; int slope_dpi = 0;
int dummy = 0; int dummy = 0;
int scan_step_type = 1; int scan_step_type = 1;
size_t requested_buffer_size, read_buffer_size;
/* compute scan parameters values */ /* compute scan parameters values */
/* pixels are allways given at full optical resolution */ /* 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 ***/ /*** 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.clear();
dev->read_buffer.alloc(read_buffer_size); dev->read_buffer.alloc(session.buffer_size_read);
dev->lines_buffer.clear(); 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.clear();
dev->shrink_buffer.alloc(requested_buffer_size); dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear(); 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; dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count;

Wyświetl plik

@ -961,7 +961,6 @@ static void gl847_init_scan_regs(Genesys_Device* dev, const Genesys_Sensor& sens
int slope_dpi = 0; int slope_dpi = 0;
int dummy = 0; int dummy = 0;
int scan_step_type = 1; int scan_step_type = 1;
size_t requested_buffer_size, read_buffer_size;
/* compute scan parameters values */ /* compute scan parameters values */
/* pixels are allways given at full optical resolution */ /* 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, : session.output_line_count,
dummy, move, mflags); 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.clear();
dev->read_buffer.alloc(read_buffer_size); dev->read_buffer.alloc(session.buffer_size_read);
dev->lines_buffer.clear(); 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.clear();
dev->shrink_buffer.alloc(requested_buffer_size); dev->shrink_buffer.alloc(session.buffer_size_shrink);
dev->out_buffer.clear(); 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; dev->read_bytes_left_after_deseg = session.output_line_bytes * session.output_line_count;

Wyświetl plik

@ -183,7 +183,7 @@ void sanei_genesys_write_pnm_file16(const char* filename, uint16_t* data, unsign
/* Read and write RAM, registers and AFE */ /* 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 /* Genesys supports 0xFE00 maximum size in general, wheraus GL646 supports
0xFFC0. We use 0xF000 because that's the packet limit in the Linux usbmon 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 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. packet is limited 61440 without any visibility to acquiring software.
*/ */
if (dev->model->asic_type == AsicType::GL124 || if (asic_type == AsicType::GL124 ||
dev->model->asic_type == AsicType::GL846 || asic_type == AsicType::GL846 ||
dev->model->asic_type == AsicType::GL847) asic_type == AsicType::GL847)
{ {
return 0xeff0; return 0xeff0;
} }
@ -273,7 +273,7 @@ void sanei_genesys_bulk_read_data(Genesys_Device * dev, uint8_t addr, uint8_t* d
target = len; target = len;
buffer = data; 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) { if (!has_header_before_each_chunk) {
sanei_genesys_bulk_read_data_send_header(dev, len); 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, dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_REGISTER, VALUE_SET_REGISTER, INDEX,
1, &addr); 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) { while (len) {
if (len > max_out_size) 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 // write addr and size for AHB
dev->usb_dev.control_msg(REQUEST_TYPE_OUT, REQUEST_BUFFER, VALUE_BUFFER, 0x01, 8, outdata); 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 */ /* write actual data */
written = 0; written = 0;
@ -1138,6 +1138,62 @@ static unsigned align_int_up(unsigned num, unsigned alignment)
return num; 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<BufferConfig, 4> 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) void compute_session(Genesys_Device* dev, ScanSession& s, const Genesys_Sensor& sensor)
{ {
DBG_HELPER(dbg); 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.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_channel_bytes = multiply_by_depth_ceil(s.output_pixels, s.params.depth);
s.output_line_bytes = s.output_line_channel_bytes * s.params.channels; s.output_line_bytes = s.output_line_channel_bytes * s.params.channels;
compute_session_buffer_sizes(dev->model->asic_type, s);
} }
/** @brief initialize device /** @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, " ccd_size_divisor : %d\n", session.ccd_size_divisor);
DBG(level, " optical_resolution : %d\n", session.optical_resolution); DBG(level, " optical_resolution : %d\n", session.optical_resolution);
DBG(level, " optical_pixels : %d\n", session.optical_pixels); 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_resolution : %d\n", session.output_resolution);
DBG(level, " output_pixels : %d\n", session.output_pixels); DBG(level, " output_pixels : %d\n", session.output_pixels);
DBG(level, " output_line_bytes : %d\n", session.output_line_bytes); 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, " enable_ledadd : %d\n", session.enable_ledadd);
DBG(level, " pixel_startx : %d\n", session.pixel_startx); DBG(level, " pixel_startx : %d\n", session.pixel_startx);
DBG(level, " pixel_endx : %d\n", session.pixel_endx); 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); debug_dump(level, session.params);
} }

Wyświetl plik

@ -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 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, extern void sanei_genesys_bulk_read_data(Genesys_Device * dev, uint8_t addr, uint8_t* data,
size_t len); size_t len);

Wyświetl plik

@ -230,9 +230,6 @@ struct ScanSession {
// the number of pixels at the optical resolution. // the number of pixels at the optical resolution.
unsigned optical_pixels = 0; 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. // the resolution of the output data.
// gl843-only // gl843-only
unsigned output_resolution = 0; unsigned output_resolution = 0;
@ -263,6 +260,12 @@ struct ScanSession {
unsigned pixel_startx = 0; unsigned pixel_startx = 0;
unsigned pixel_endx = 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 // whether to enable ledadd functionality
bool enable_ledadd = false; bool enable_ledadd = false;