Draft: PSD: refactor, modernize, upgrade, optimize, and implement missing features
In this PR I apply the same drill as in !1695 (closed). For the present branch, I grabbed the 80-layer PSD file we got from https://bugs.kde.org/462417 and profiled it. The results will speak from themselves:
Before | After |
---|---|
For the save, the improvements are smaller but still meaningful (after CFG overhead).
Before | After |
---|---|
New features
-
Progress updater
Breaking changes
None. There was little need for clang-tidy here, fortunately.
Performance highlights
- In KisPainter, I switched to the tile accessor for 25% cheaper transparency checks on opaque pictures (tested with https://bugs.kde.org/444844)
- 18% less time spent exporting the channel panels by inline templating the color space checks
- 10% less time RLE compressing the rows by reworking of the compressor logic
- 50% less time spent accessing pixels individually by switching to the tile accessor
- A simple 3% speedup by caching the layer info record instead of copy-constructing it when checking it for the compression type
Reading pixels
87% of the time of the old readChannelValue() function, the workhorse of pixel reconstitution, was taken in QMap innards and the constant virtual function calls. Here I:
- switched to a
const std::map
for accessing the channels, which is a true O(log n) container and does not allocate within accessors - made the layer info records const and memory managed
- took all bounds checks out of the hot path, by caching the pointers before reconstituting the row
- fixed some inlining issues in KisRLE::decompress(), brought by QByteArray container iterators being virtual function calls, instead of inlinable pointers
- employed my templated inlined functions trick to perform the color space and compression checks only once, instead of in every pixel.
And, only once per chunk of contiguous rows:
- cached the PSD row data reusing the same map strategy as above
- this had the added benefit that the channel could be accessed only once, at the row start, and only the pointer is shipped around
- performed the bounds check and early rejected the PSD as malformed
Test Plan
Build Krita and try using PSD files.
Formalities Checklist
-
I confirmed this builds. -
I confirmed Krita ran and the relevant functions work. -
I tested the relevant unit tests and can confirm they are not broken. (If not possible, don't hesitate to ask for help!) -
I made sure my commits build individually and have good descriptions as per KDE guidelines. -
I made sure my code conforms to the standards set in the HACKING file. -
I can confirm the code is licensed and attributed appropriately, and that unattributed code is mine, as per KDE Licensing Policy.