In week 8 I started working on a part of the Krita I had never touched before. It is actually a library inside KOffice called Pigment. Pigment is responsible for the color management. It contains some colorspaces we actually don’t use in Krita because they are too simple for Krita’s needs. They are intended for use by other applications in KOffice. So far the applicationss do not have color management, but they can if the developers want it. Pigment contains many useful classes which operates on the color in some colorspace in many ways like doing the math, compute the histogram. It also contains the implementation of the composite operations. And here was my interest as we wanted to try to vectorize the composite operations by using SSE instructions and the vectorization feature in GCC4.x.
So first I started to write benchmarks for the various composite operations. And then I started to work with GCC feature. Vectorization of the composite operation is already implemented in GEGL by Øyvind Kolås. Also GIMP 2.6.x is using MMX, SSE, SSE2 so I had inspiration and I was trying to map it to our implementation of composite operations. GEGL is using nice code, but GIMP is using assembler directly. I don’t have much experience with assembler. I wish I had write assembler lessons previous year at the university. It is not hard
to code something, but it is hard to do it correctly. I read somewhere in Inkscape mailing list that they had some assembler code to speedup some work but it ended up to be slower then code optimized by compiler.
I had quite a hard time and I did not manage to implement the vectorization even with help I get regularly from Cyrille and boud and other Krita hackers and
GEGL hacker. We stopped it on Wednesday because we discovered that the issue is more complicated then we thought and it would require much more than two days to finish. Maybe another week or even weeks. And the result could be not faster. One of the problems we discovered was that the RGBA 8-bit colorspace uses the unsigned char datatype (quint8 in Qt) for the memory storage but when you do a composite operation, you have to retype it to the bigger data type like a int32. Why? If you have a pixel in quint8 with value 255 and other pixel with value 200 and you add or multiply them, you overflow the data type. And the result is bad. If you retype, you have solved that issue. I studied the GIMP code and how it is
implemented there. It is solved using MMX instuctions for this case. The MMX technology supports both saturating and wraparound modes. You can read about that more in details here. Another issue was that GIMP does not compute every composite operation with vectorization but only some composite operations are implemented this way.
So we decided to start to work on the other item in the action plan which is mirroring of the canvas and possibly rotation. On Thursday and Friday I was back in the canvas code. So far I have working code of the mirroring of the events from input devices. Now the hardest part will be to implement mirroring in the projection. Projection is the code responsible for correct displaying of the zoomed image and it computes the image you see in the canvas when you scroll or move or some tool paint it’s outline or some part of the
image is changed by some tool. The task will continue also for OpenGL canvas as we have two canvases in Krita.
You see, the vectorization week does not bring any speedup, but I don’t want you to be sad so I decided to write a blog post about other Krita work I do in my spare time. Read it here.