Painting on selections and selection masks

Boudewijn Rempt boud at
Sat Oct 29 18:06:34 UTC 2011

On Saturday 29 October 2011 Oct, Dmitry Kazakov wrote:

> Btw, I have an idea! Why do we need a special colorspace for masks at all?
> Just leave it alpha and add a composite op that merges grayscale colorspace
> of the dab into alpha colorspace?

We did try that before, it didn't work.

> All the users who rely on alpha channel
> will continue work as they used to work. The users who know about the
> colorspace of the dab will use the conversion indirectly.


> Sure we don't paint on nodes. We paint on their paint devices. But the nodes
> tell us *how* to paint on their paint devices. Just look at the
> KisPaintLayer::channelLockFlags(). Do you think it is wrong as well? Should
> we delete this code then? ;)

Completely different situation. Enabling/disabling channels is a gui function that doesn't change the colorspace.

Having a special function on KisNode just to get a colorspace+alpha if the node's paint device has a colorspace-alpha is not good api. Even on KisPaintDevice it would be bad api, since the +alpha colorspace can be calculated from the the -alpha colorspace and there are _no_ other situations where we'd want to create a dab in a different colormodel from the one of the paint device.

If at all, an extra method on KoColorSpace could be used, but even that would be a hack.

> > > Well, I don't think that KisSelection is a proper place for doing this.
> >
> > Why not? That is the interface between things to paint on (the mask's paint
> > device) and the selection itself (the selected bytes). It's the only point
> > where the two assumptions Krita is built on come together: painting needs an
> > alpha channel, masking needs a single byte per pixel.
> >
> 1) It triples (in the best case doubles) memory usage.

From a design pov, irrelevant; we already have a projection mechanism there.

> 2) It makes us call update projection regularily, that takes time.

From a design pov, irrelevant; we already have a projection mechanism there.

> 3) It makes us work directly with bytes outside pigment, that is a wrong
> thing.

Implementation detail; using pigment to convert from graya to a, where the gray channel is put in the alpha channel is trivial. It's also not interesting.

> 4) It throws away all the device sharing optimizations we have in
> KisSelection.

Same issue as 1)

>  > As I
> > > And I don't even speak about the ability to
> > > use 8/16 bit selection masks in the future.
> >
> > Well, that's a lot easier to do if everything is contained inside
> > KisSelection. Though I don't think we'll ever do 16 bit selections, no user
> > has ever asked for it.
> >
> I think they've never asked about it, because it is impossible now to paint
> semi-transparent masks. So they cannot see granularity of the mask at all.

It's possible in other apps and there users don't need the feature either. Non-binary selection masks are used to give selections a soft edge: 8 bits are enough for that, in practice, apparently. 

In any case, it's not a consideration that is relevant for fixing a critical bug for the 2.4 release.

> The problem is, there is no way to solve memory problem within the confines
> of your design at all. In your solution there is just no way to avoid
> doubling of memory. It is not a problem of a particular implementation. It's
> just a problem of the design itself. So to fix this issue in the future
> (say, after the release) we'll have to revert all this work and do it again
> from the very beginning. Why do the work twice? 

Because there is no way to solve the bug otherwise without touching either all of pigment or all of Krita, which is not going to happen between beta 3 and release candidate 1.

> Our selections are not very
> fast currently, why making them slower and more hungry while we have another
> way of doing things which is faster and doesn't double memory consumption?

Because they don't work. And they should work.

> Ok, just to be more objective in our conversation, let's fill the
> requirements for the system we want to get. What do we actually need?
> 1) We need to be able to paint with a brush with transparency onto
> selections, that is "with grayscale brush of any form" onto a selection.
> Selectedness is controlled by gray channel, alpha channel of the mask is
> just used for forming a shape of the brush.

No: we need to be able to use any pixel manipulation part of Krita, from brushes to filters, on the global selection or any mask. 

> 2) Selection (at least their projections) should be single-channeled,
> because pigment uses only 1 channel for transparency.
> 3) Some of the tools (like KisFillPainter) work directly with the byte of
> pixel selection, so such tools should be dealt with (fixed, if needed)
> gracefully.
> 4) We shouldn't double the memory consumption of selection, when it is
> possible to avoid this. No additional iterations through the selection as
> well, because it takes time on large images.
> 5) All the tools (esp. Gradient and Fill) should take global selection into
> account when painting on a mask. Otherwise there is no point in using them.
> Are there any other requirements I forgot about?

Yes: needs to be done in time for the 2.4 release without breaking all of Krita.

Krita currently is, from the canvas to the filters, from the tools to the projection update full of unfinished refactorings. We are not going to do another big refactoring between now and RC1.

> Could you answer the following questions:
> 1) How does you design fits them?

It will make masks work the way users expect them. This is the only criterion that counts.

> 2) Is it possible to fit all the requirements in the future (on the next
> iteration of your work, that is after the release)?

Who knows? After the release, we can look forward. We cannot release with this bug present.

Boudewijn Rempt,,

More information about the kimageshop mailing list