Painting on selections and selection masks

Dmitry Kazakov dimula73 at gmail.com
Sat Oct 29 10:24:55 UTC 2011


> > > I'm not convinced that we're just having problems with dabs -- I think
> it's
> > > a more general problem, that shows up everywhere in krita where we
> > > manipulate paint devices.
>
> Could you make a couple of examples? I don't get it.
>
> The hairy brush doesn't create dabs, the fill tool doesn't create dabs, the
> gradient tool doesn't create dabs -- and they all need an alpha channel to
> work correctly.
>

Hairy Paintop create a fixed paint device dab, that is then bitBlt'ed onto
the device, so there is no problem with it.
KisFillPainter works directly with a single byte of the pixel selection, so
your solution will break it.
KisGradientPainter works directly with bytes of the device, that is it will
work as before (so not as we want it to) if we introduce a new composite op.
The problem can be easily solved by adding colorSpace->bitBlt() calls to the
code of the gradient painter.


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? 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.



>  > > And there's no need to actually solve it at the node level, that's too
> high
> > > up.
> >
> > I don't think this is too high up. A node reports which colorspace you
> > should paint *on it* with. Probably, even usual colorSpace() method is
> > capable of doing this, but I'm not sure it'll work. It needs thorough
> > investigations.
>
> We don't paint on nodes, we paint on paint devices. Adding api for painting
> to KisNode is certainly wrong.
>

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? ;)
I think such hints for tools are fine (except for LSP problem of
channelLockFlags(), but this is a different issue).



> > As I said the api of the KisPaintDevice shouldn't (and mustn't) be
> changed.
>
> Sorry, then your solution will not work. KisNode is the wrong place, since
> we do not paint on nodes.
>

Commented above.



> > 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.
2) It makes us call update projection regularily, that takes time.
3) It makes us work directly with bytes outside pigment, that is a wrong
thing.
4) It throws away all the device sharing optimizations we have in
KisSelection.


 > 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.


 > And triple memory usage is hardly acceptable as well.
> That is the only big problem I see. But given that this is a critical bug
> for the 2.4 release, I think it could be acceptable. There is no other way
> to fix the problem.
>

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? 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?


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.
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?

Could you answer the following questions:
1) How does you design fits them?
2) Is it possible to fit all the requirements in the future (on the next
iteration of your work, that is after the release)?


-- 
Dmitry Kazakov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kimageshop/attachments/20111029/19765fda/attachment.html>


More information about the kimageshop mailing list