<html>
<body>
<div style="font-family: Verdana, Arial, Helvetica, Sans-Serif;">
<table bgcolor="#f9f3c9" width="100%" cellpadding="8" style="border: 1px #c9c399 solid;">
<tr>
<td>
This is an automatically generated e-mail. To reply, visit:
<a href="http://git.reviewboard.kde.org/r/104052/">http://git.reviewboard.kde.org/r/104052/</a>
</td>
</tr>
</table>
<br />
<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
<p style="margin-top: 0;">On February 23rd, 2012, 8:56 p.m., <b>Christoph Feck</b> wrote:</p>
<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
<table width="100%" border="0" bgcolor="white" style="border: 1px solid #C0C0C0; border-collapse: collapse; margin: 2px padding: 2px;">
<thead>
<tr>
<th colspan="4" bgcolor="#F0F0F0" style="border-bottom: 1px solid #C0C0C0; font-size: 9pt; padding: 4px 8px; text-align: left;">
<a href="http://git.reviewboard.kde.org/r/104052/diff/2/?file=50867#file50867line106" style="color: black; font-weight: bold; text-decoration: underline;">kdeui/util/kimagecache.cpp</a>
<span style="font-weight: normal;">
(Diff revision 2)
</span>
</th>
</tr>
</thead>
<tbody style="background-color: #e4d9cb; padding: 4px 8px; text-align: center;">
<tr>
<td colspan="4"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">KImageCache::~KImageCache()</pre></td>
</tr>
</tbody>
<tbody>
<tr>
<th bgcolor="#b1ebb0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2"></font></th>
<td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
<th bgcolor="#b1ebb0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">105</font></th>
<td bgcolor="#c5ffc4" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "> <span class="n">stream</span> <span class="o"><<</span> <span class="n">image</span><span class="p">.</span><span class="n">format</span><span class="p">();</span></pre></td>
</tr>
</tbody>
</table>
<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">This fails to correctly handle palettized images.
If we do not want to preserve image texts, gamma, and DPI, please document it (the PNG handler did).
Also, did you try setting the compression level for the PNG writer before giving up on compression? The compression is probably wanted. I have not checked if Qt uses quality 0 or 100 for the fastest mode, but the default PNG compression is utterly slow (as you noticed ;)</pre>
</blockquote>
<p>On February 23rd, 2012, 9:08 p.m., <b>Mark Gaiser</b> wrote:</p>
<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Don't know about that.. Hope someone more knowledgeable could respond in the "image texts, gamma, and DPI".
As for the fastest/slowest mode. No, i haven't tried that. But even then it seems kinda strange to load an image and directly save the exact same image as .png in some mmapped file (which was the behavior). Saving the "compiled" image (the bits) seems more obvious.</pre>
</blockquote>
<p>On February 23rd, 2012, 9:40 p.m., <b>Christoph Feck</b> wrote:</p>
<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
<pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">The KImageCache is not used exclusively for "loaded" images, but also (and especially so) for generated images, e.g. when caching SVG rendered data.
Regarding compression, the type of images that are stored in the cache are usually very compressible, better than text, and thus the memory (or even disk) pressure can be greatly reduced. For example, the 128x128 "text-x-generic" icon is 64 KB uncompressed, while only 13 KB compressed.
I just checked Qt docs. If you use "image.save(buffer, "PNG", quality);" you get uncompressed PNG with quality == 100, and fastest, but moderate compression with quality == 80. Any smaller value improves compression rate, but makes it slower.</pre>
</blockquote>
</blockquote>
<pre style="margin-left: 1em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I played a bit with compression and got it working.
The cached sizes (with qCompress(data, 5)) are indeed _way_ smaller then uncompressed. However, it crashes quite often when i use that. Here is the raw code for it: http://paste.kde.org/428102/
The unit tests pass on it yet kwin crashes on the image with this key: "15_1680_1015_hover-_widgets/viewitem". I haven't done further tests.
Compression rate is quite high:
key: "8_8_/usr/share/apps/desktoptheme/default/widgets/viewitem.svgzhover-bottomleft"
cachedData size (compressed): 151
cachedData size (uncompressed): 256
key: "8_8_/usr/share/apps/desktoptheme/default/widgets/viewitem.svgzhover-bottomright"
cachedData size (compressed): 149
cachedData size (uncompressed): 256
However, zlib is slow. If we really desperately want to have compression then we should go for something fast even if it doesn't compress as good: http://code.google.com/p/lz4/ The speed is about 20x faster with LZ4 then it would be with zlib but obviously with a lower ratio. Please do note that adding LZ4 is not hard, it's only 2 files (1 .c and 1 .h)
What i do find strange is that the file sizes of the caches seem to remain the same with and without compression. Yes, i do delete them prior to testing.
I leave it up to you guys where we go from here. I'm fine with adding compression (nice new interesting challenge ^_^), but i'm also fine with leaving it the way it's now in the diff + the edit from Aaron J. Seigo.</pre>
<br />
<p>- Mark</p>
<br />
<p>On February 23rd, 2012, 7:23 p.m., Mark Gaiser wrote:</p>
<table bgcolor="#fefadf" width="100%" cellspacing="0" cellpadding="8" style="background-image: url('http://git.reviewboard.kde.org/media/rb/images/review_request_box_top_bg.png'); background-position: left top; background-repeat: repeat-x; border: 1px black solid;">
<tr>
<td>
<div>Review request for kdelibs, David Faure and Michael Pyne.</div>
<div>By Mark Gaiser.</div>
<p style="color: grey;"><i>Updated Feb. 23, 2012, 7:23 p.m.</i></p>
<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Description </h1>
<table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
<tr>
<td>
<pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I was running KWin through callgrind to see where possible bottlenecks are. I wasn't expecting much since it improved greatly during the 4.8 dev cycle, however one stood out. The saving of PNG images was taking about 1/5th of the time in KWin that i could see directly. That looked like something i might be able to optimize.
What this patch is doing is storing the actual image bits to prevent saving a PNG image to the mmapped cache. That was a hot code path in time (cycles), not even in calls. I've also reduced the amount of memory copies to a bare minimum by adding a rawFind function to KSharedDataCache which fills a QByteArray::fromRawData thus preventing a expensive memory copy. The rawFind is used for looking up an image and fetching it's data without copying it. That is done because QImage seems to make a copy itself internally. I don't have any performance measurements, however, prior to this patch my kwin test was using up ~5.000.000.000 cycles. After this patch it's using up 1.370.000.000. I don't have raw performance numbers to see if the cache itself is actually faster, it certainly has become a lot cheaper to use the cache. Logic wise i would say creating a QImage from the cached data should be way faster now since there is no step involved anymore in decoding the image. Storing is certainly an order of magnitude faster.
Benchmark numbers. insert(write) and find(read)
-- Before patch --
READ : 0.019 msecs per iteration (total: 79, iterations: 4096)
WRITE: 0.010 msecs per iteration (total: 88, iterations: 8192)
-- After patch --
READ : 0.019 msecs per iteration (total: 79, iterations: 4096)
WRITE: 0.0026 msecs per iteration (total: 87, iterations: 32768)
Reading is equal in speed, writing is ~5x faster after the patch.
Special thanks go to David Faure for helping me a great deal with this.</pre>
</td>
</tr>
</table>
<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Testing </h1>
<table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
<tr>
<td>
<pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">I've also written a bunch of test cases (greatly improved by David Faure) to see if i didn't break anything. According to the test (which is also comparing the actual image bits) it's all passing just fine.</pre>
</td>
</tr>
</table>
<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Diffs</b> </h1>
<ul style="margin-left: 3em; padding-left: 0;">
<li>kdecore/util/kshareddatacache.h <span style="color: grey">(339cecc)</span></li>
<li>kdecore/util/kshareddatacache.cpp <span style="color: grey">(9fe3995)</span></li>
<li>kdeui/tests/CMakeLists.txt <span style="color: grey">(63788f6)</span></li>
<li>kdeui/tests/kimagecachetests.h <span style="color: grey">(PRE-CREATION)</span></li>
<li>kdeui/tests/kimagecachetests.cpp <span style="color: grey">(PRE-CREATION)</span></li>
<li>kdeui/util/kimagecache.cpp <span style="color: grey">(a5bbbe1)</span></li>
</ul>
<p><a href="http://git.reviewboard.kde.org/r/104052/diff/" style="margin-left: 3em;">View Diff</a></p>
</td>
</tr>
</table>
</div>
</body>
</html>