Project

General

Profile

Feature #11978

print in background

Added by Dan Torop 7 months ago. Updated 4 months ago.

Status:
Fixed
Priority:
Low
Assignee:
-
Category:
Printing
Target version:
Start date:
01/29/2018
Due date:
% Done:

100%

Affected Version:
git master branch
System:
all
bitness:
64-bit
hardware architecture:
amd64/x86

Description

Making the "print" button in the print view do its work in the background could improve dt's print functionality. On a slower computer, or for an image with many iops enabled, 5-30 seconds can elapse between pressing the print button and the job being handed off to CUPS. In the meantime, the UI freezes, and there is no visual feedback that the print button has been pressed. For making a series of minimally corrected prints, printing in the background would allow the user to stay in the flow of the work. Immediately after pressing "print", once could switch back to lighttable, find the next image to work on, and even have the work on it in darkroom be complete by the time the printer has done its work.

Making print happen in the background would change its behavior to be in line with the "export" feature of the lighttable view.

This could also lead to another feature -- making a global shortcut key ctrl-P such that it would be possible to print the current image in lighttable or darkroom view with the current print settings.

I'd be happy to work on this if it were considered a useful feature, but also understand that Pascal Obry and other dt developers may have the most familiarity and alacrity with the relevant code.

Associated revisions

Revision e6e02e63
Added by Dan Torop 6 months ago

print: print in background

Now that laid groundwork by having a separate print function and
encapsulating state, actually print in the background thanks to the
jobs mechanism.

This fixes #11978.

History

#1 Updated by Dan Torop 7 months ago

Of course a counter-argument to print-in-background would be that on a machine slow enough such that printing is this laggy, working on another image while print is working would be quite slow.

#2 Updated by Pascal Obry 7 months ago

I'm not sure this will do some good. In fact after each print I look at the picture to see if the color is ok and if there is not head-cleaning to do. On my photo club we have an Epson 4900 which is quite delicate and need lot of attention. So doing print in background as a batch processing as you suggest may lead to cause more problems than it solves. Not counting on your quite good counter argument about the speed. All in all, I don't see this as a good idea.

#3 Updated by Dan Torop 7 months ago

Pascal: Thanks for the thoughts on this. I see a useful and a not useful case for background printing:

  • USEFUL Making a bunch of quick work prints: A user has a fairly reliable printer hooked up and decent color management. The user wants to make dozens of small work prints at a sitting of candidate pictures. The user doesn't want to rely on the SOC JPEG nor trusts a one-size-fits-all style. Hence it's worth spending 1-2 minutes to correct white balance and craft a tone curve (and generally make sure other iops are at sane values) for each picture. The result will be adequate, though not great, prints. The goal is to keep the printer running and do what good one can in the intervals that the printer runs.
  • NOT USEFUL The results of the useful case is a bunch of prints to review, say by pinning up on the wall or discussion with others, which leads to making picks for good printing. Then comes the case which Pascal describes, in which one makes a few good prints. You do your best to make corrections, run a print, and wait until that print is complete before going back and making further corrections. This cycle will repeat multiple times.

Admittedly, this style of work comes from the days of analog darkroom photography, when one really needed a work print to figure out whether there was potential in something which looked good on the contact sheet. But I find that even with full-screen views of images in lighttable, that a moment's tuning work and a paper print gives me a much clearer idea of which images have potential. There's a Dan Margulis essay positing the color-correction steps necessary if one only had a single minute to work on each picture. Background printing lends itself to that style of work. Some prints still come out so lousy that the require further correction, but it's always possible to backtrack to the problem raw and work on it one more time.

Though this isn't specifically a darktable problem, I should note that when I am making a lot of pictures at a sitting, I have the tendency of, while waiting for a print, switching to the web browser and reading news. I then spend longer on the web browser than it takes for the print to finish. If dt were immediately responsive post-print. Admittedly, internet-blocking software could solve this problem as well.

#4 Updated by Tobias Ellinghaus 7 months ago

I agree that moving the image processing and subsequent printing to a background job is a good idea. If a user decides to not do anything in the meantime that's his choice, but at least it would be possible to do other things. So I don't really see what counter arguments there are.

#5 Updated by Dan Torop 7 months ago

It's certainly a feature I wish for most days I print, and hence, selfishly, one I'd be happy to work on.

Another point in favor is to not confuse new users of dt print -- they may expect it to work more like export (with a progress bar), and be frustrated when the UI freezes up. Under Gnome, if I switch away from dt then back while a print job is processing, I see a "darktable is not responding" dialog. This suggests something is awry, when dt is actually just doing its work.

A point against adding background print is that the print code would be in even more places. Currently there's relevant code in src/common/, src/libs/, and src/views/. This feature would presumably move a bunch of code from print_settings.c (from _print_button_clicked() plus dependencies) into src/control/jobs/.

#6 Updated by Tobias Ellinghaus 7 months ago

No need to have anything in control/, you can keep the callbacks in the current place. In newer code we do that all the time.

#7 Updated by Dan Torop 6 months ago

No need to have anything in control/, you can keep the callbacks in the current place. In newer code we do that all the time.

Thank you, helpful!

I worked up an implementation:

https://github.com/darktable-org/darktable/compare/master...dtorop:print-in-background

I like it a lot: the print view feels more responsive, and it even feels like print jobs are running faster, because of the slight visual feedback. It is a substantial diff, but actually doesn't change the flow of the current code too much.

Some open questions/comments:

  • I added a progress bar so that it is possible to cancel printing after the export stage. I find this useful, as I sometimes have regrets after hitting print, but understand that this may be bikeshedding.
  • Similarly, the print job is now identified by either title (if available) or filename. This adds some extra code. Again, I find this useful, but I don't want to make the code verbose for a single use-case. I also don't know if I need to filter non-printables from the title, as in metadata_view.c.
  • I kept to the extant code where some of the parameters are coming via dt_conf_get_*(), others via dt_lib_print_settings_t. Would it be better to get all the parameters via dt_lib_print_settings_t? These should be the same as what's in the conf file, and require less code to fetch.
  • I believe that I fixed a memory leak (https://github.com/darktable-org/darktable/blob/b630b911e917b8d4b546537ba6a8fbc1a7c7ceba/src/libs/print_settings.c#L290) by which the export buffer wasn't freed if the print profile is not available. This buffer will now always be freed via _print_job_cleanup().
  • In the name of having as much cleanup code in one routine as possible, the export buffer isn't freed until the print job is disposed of. Previously this buffer was freed the moment the PDF file was created.

It also occurred to me that a really fast print implementation could speculatively process the image in the background the moment it was selected in print view, such that in the best case, when the user clicks "print" a completed PDF could be sent directly to dt_print_file()! Even if the user changes the buffer profile, the code would at least have worked through the pipeline up to the colorout iop. The cost would be code complexity and having lots of excess CPU use in the event the user is clicking through images on the filmstrip or entirely opts not to print the image which they are viewing.

Regardless, I'd appreciate any thoughts on my print-in-background branch. I'll certainly use it some more here before thinking about making a PR.

#8 Updated by Tobias Ellinghaus 6 months ago

  • Status changed from New to In Progress
  • % Done changed from 0 to 50

There are a few small problems (for example a use-after-free of params->p_icc_profile) but in general I like it. Instead of all the intermediate freeing in _print_job_run() I'd move all of that into _print_job_cleanup(). And maybe the progress bar should be set to 1.0 only after the image was sent to the printer? Just in case that can block.

Pascal, what do you think about it?

About exporting images speculatively I am not sure that the added code complexity would justify the gains.

#9 Updated by Dan Torop 6 months ago

Tobias Ellinghaus wrote:

There are a few small problems (for example a use-after-free of params->p_icc_profile) but in general I like it. Instead of all the intermediate freeing in _print_job_run() I'd move all of that into _print_job_cleanup(). And maybe the progress bar should be set to 1.0 only after the image was sent to the printer? Just in case that can block.

Thank you for looking this over. I think I fixed all of the above mentioned. Now _print_job_cleanup() does a lot more work, including unlink()-ing the temporary PDF file. I also added a dt_control_log() message when the processing starts, in keeping with what export does, and what print already did before these changes.

About exporting images speculatively I am not sure that the added code complexity would justify the gains.

Yes, I agree, it was a bit of a wild thought. The only way I could see it working would be if the pipeline cached results during exports (which doesn't happen now?) when called from the print view, such that this would be transparent to print itself.

#10 Updated by Dan Torop 5 months ago

  • Status changed from In Progress to Fixed
  • % Done changed from 50 to 100

#11 Updated by Roman Lebedev 4 months ago

  • Target version set to 2.6.0

Also available in: Atom PDF