Future changes to the processing pipeline

I have just finished implementing some substantial changes to the processing pipeline, which boil down to the introduction of the concept of a “default” input for the processing nodes (or “layers”).

Why this is important?

One of the problematic aspects of the current processing pipeline are “mask layers”, i.e. tools added in order to build the opacity mask of a layer. In the current implementation, if one starts from an empty mask and adds a “curves” layer, nothing happens, because there is no “default” input for the curves tool. Instead, one has to explicitly insert a “clone layer” instance below the curves in order to provide some input data.
This is complicated and non-intuitive…

The new implementation simplifies the workflow (at least I hope so…). Suppose one starts with two layers L1 and L2 (L2 is above L1), and adds a curves layer to the initially empty mask of L2. The new code will automatically generate a grayscale version of the output of L1, and will feed it to the input of the curves tool in the L2 mask. This is assumed to be the most obvious “default” decision from the user’s point of view, but the source layer can be customized if the user has something else in her/his mind.

The name of the layer that is used as “default” is always shown and updated in the UI, so it is always possible to see exactly what the program is doing:

To save vertical space, the layer blending controls and the input selection have been also moved to a separate tab in the tool controls dialogs.

The new pipeline implementation should be fully backward-compatible, and old files with “clone layer” instances or other custom layer input configurations should be processed exactly the same way as in the past. However, before merging the changes to the stable branch I want to be 100% sure that there are no problems with old files, and also get some feedback about what I have described.
If you feel brave enough, you can grab test builds from the simplified-pipeline branch from the usual continuous release page.

Another change I am testing concerns the addition of new layers. Instead of a dialog, I am testing a menu-based approach, which should involve less mouse clicks. Here is how it would look like:


What do you think?


It looks like the simplified-pipeline build is only available as an AppImage - any chance of a macOS build?

The default mask input will be useful - most of the time you just want to use the output of the previous layer. Clone layers are less useful than the proposed default because they are connected to a specific layer, so you have to edit the clone layer if you move the parent layer in the stack…

Would it make sense to make the default be the input source of the layer attached to the mask, rather than the previous layer? Most of the time it would be the same (because most layers are set to ‘process prevous layer’), but sometimes it isn’t.

That would make things quicker for sure. I am still hoping for a search function. :wink:

MacOS and Win64 builds are now available as well.

Not really… the clone layer remains “locked” to its source layer even when it is moved in the stack. Or have I mis-intepreted your remark?

What you propose makes perfect sense! I will try to implement it in the next version of the simplified-pipeline packages…

1 Like

I have just finished implementing what you proposed, and also fixed some “glitches” in the default input handling. Packages should appear soon in the continuous integration release as usual…

1 Like

I’ve just tried HEAD-d1bd3 on the mac:

  1. The menu based interface for adding layers works really nicely. Much smoother than the tabbed lists interface.
  2. The default mask input works as expected.
  3. You can’t see the input controls if you don’t use the floating tool controls
  4. It is possible to get into a state where Photoflow cycles endlessly through Processing…Caching…Processing…Caching…
    One way to get this to happen is:
  • Open a raw file
  • Turn off the RAW loader layer
  • Turn the RAW loader layer back on
  • Photoflow starts cycling between Processing…Caching… endlessly
  • If you turn the RAW developer layer off and on again, it resets.

I have also managed to get into this state by changing the input of a mask layer, but I haven’t been able to reproduce that one.

I went back to the stable version to test the above (its not a problem with stable BTW), and the simplified-pipeline UI is much nicer to use. :smiley:

I have encountered these before. Seems to me that I can crash PF by changing values or toggling options too quickly in succession.

I’m really happy you like it!

I have changed again the default for mask layers. Now the initial layer in a mask will take by default the output of the associated non-mask layer. The flow looks more or less like this:

This is obviously configurable, but for me this represents a more common default use-case. What do you think?

I will look into this… although hiding the RAW loader layer is not really what you would normally do. I will probably introduce the concept of “input layers that cannot be hidden”.

After a little bit more testing, I think I will merge the changes into stable without waiting too much, if we all agree…

I suspect that this has more to do with threads synchronization. GTK is not thread-safe, and making the UI work correctly with a multi-threaded processing pipeline is a real PITA. Most of the crashes I have been fixing over the past couple of years were related to threaded access to GTK functions… and I still have tons of such issues to fix!

1 Like

Ah, you give me a different experience to consider regarding my random crashes in rawproc. I’m only seeing such with the GTK rendition, maybe one more consideration in choosing my next GUI toolkit…

@paulmiller @afre this is how the “simplified” UI looks like right now:

I would prefer the default to take the input to the mask from the input of the associated non-mask layer rather than the output:

My reasoning for this is that then the mask does not change as you edit the settings on the layer.

I wouldn’t normally hide the RAW loader layer, it was just the simplest way I could get the problem to occur. It happens when I use the shadows/highlight layer, but not 100% reproducably.

To me it could go either way. I understand your method: process input into layer, then dial it back using mask.

It’s been a while since I used photoflow.
Today, I decided to use it on a couple of family photos and I must say I’m impressed.
It seems way faster than before (but I still get the annoying “caching…” that swallows 100% CPU, sometimes).
I got excellent results with a minimal set of nodes, and I was also happy to see that an old preset you did (Edge Sharpening) still works and rocks. Btw, it would be nice to have a tool for that. I lost some time trying to remember which nodes among many were the tweaking ones.
Also, the tone mapping tool gives wonderful results.
Besides the caching thing, sometimes I can’t see the close button from a floating tool (a big one like tone mapping), but that’s not really an issue.
Thanks to all that contribute to this good work (the developer, obviously, but also the testers).
Just a feedback.

1 Like

I’m very happy to hear that, you truly made my day!

The caching is needed to pre-compute cpu-intensive layers in the background, so that the processing time does not explode… ideally this should not be needed, but for the moment that was the best compromise I could find.

Indeed I have been putting quite some efforts into backward compatibility, and it looks like it was done properly :wink:
I have some ideas to use the guided filter for that, and as you say eventually put that into a separate tool.

That should improve with the UI layout I am proposing in this thread. For example in the tone mapping case:

I have just pushed a change that reverts back the code to what you suggest. Moreover, the input list for mask layers will also contain the output of the parent non-mask layer before blending, so that my previous idea can still be realized…

Pre-compiled packages will be available in a short time. I’d appreciate some feedback on this new version, as I would like to merge those changes into the stable branch as soon as things look OK.


1 Like

Will check it out. The branch is ready for merging as far as I can tell.

I’ve given 9c527 a quick try. The user interface works really well, but there are a some strange problems that you may want to fix before merging:

  1. If I add 2 layers and put a mask on the first one, the result is odd:

If I turn the mask off, or explicitly choose the input for the top layer, I get the result I expect.
IMG_9010_TEST.pfi (22.1 KB)

  1. Still not reproducable, but I got the Processing…Caching…Processing loop the first time I tried to add a Shadows/Highlights layer.

  2. Dragging to reorder layers doesn’t seem to work any more.

I pushed a fix for this, the code should now avoid using a mask layer as the input for a non-mask one…

Good catch! I am now trying to fix this… thanks!

Right. What hurts more, though, is the swap usage. When it starts caching and I still have plenty of ram available, only high cpu usage is noticed, and I can perfectly deal with that. But then ram is filled up and it begins to swap. Then my computer becomes useless. The only way to stop that is a hard reset. Not sure if this is an Ubuntu stuff. I will play with swapiness values the next days to see what happens. Currently, swapiness is 60 in my Ubuntu settings.

Been wondering for a long time: could we get a panic button or key combination that would stop operations when things get out of hand? E.g., Esc. After which everything is cached from scratch. It is inelegant but it would save the app from stalling or crashing, and we wouldn’t lose our cool, esp. when we are in the zone. :sunglasses: