<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>[A5] Reading from bitmaps is amazingly slow</title>
		<link>http://www.allegro.cc/forums/view/617191</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Tue, 26 Dec 2017 17:05:38 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I switched to memory bitmaps. It is faster but still way too slow.</p><p>All I&#39;m doing, is a single pass of two for-loops to convert a bitmap into an array.</p><p> Back in the A4 days I&#39;d use al_get_pixel for collision detection with pixel maps. But in A5 it&#39;s way too slow sitting on the videocard, so you&#39;d use system bitmaps. But the system bitmaps aren&#39;t as fast as they should be. Checking for collisions by using al_get_pixel on a memory bitmap in A5 is a noticable burden on my profiling. So I convert the memory bitmap to an array. It works way faster... except the conversion phase which now gives my prototype game a huge startup time:</p><p> - Normal/video bitmaps: 70 seconds<br /> - System bitmap: 10 seconds (definitely better!)</p><p>Source bitmap (PNG) is 10000x1500 </p><p>10 seconds to do 10000x1500 = 15,000,000 reads. 1.5 million a second sounds fast but we&#39;re talking simple reads. </p><p>Maybe I&#39;m thinking too hard and it&#39;s &quot;fast&quot; for what I&#39;m doing and I&#39;m just doing something &quot;silly&quot;. My computer is a slower platform, a Celeron Chromebook. But I can run my game at 115+ FPS with 1200+ blended clouds being rendered just fine. But now, it takes 10+ seconds to boot it just to convert the bitmap to an array.</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">void</span> parse_map_bitmap_into_array<span class="k2">(</span><span class="k2">)</span>
<span class="number">  2</span>  <span class="k2">{</span>
<span class="number">  3</span>  <a href="http://www.allegro.cc/manual/ALLEGRO_COLOR"><span class="a">ALLEGRO_COLOR</span></a> c<span class="k2">;</span>
<span class="number">  4</span>  <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"Converting world bitmap [%i, %i] to array. This will take a moment.\n"</span>, map_mbmp.w, map_mbmp.h<span class="k2">)</span><span class="k2">;</span>
<span class="number">  5</span>  <span class="k1">for</span><span class="k2">(</span><span class="k1">int</span> i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> map_mbmp.w<span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
<span class="number">  6</span>    <span class="k2">{</span>
<span class="number">  7</span>    <span class="k1">if</span><span class="k2">(</span>i % <span class="n">1000</span> <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"%i\n"</span>, i<span class="k2">)</span><span class="k2">;</span>
<span class="number">  8</span>      
<span class="number">  9</span>    <span class="k1">for</span><span class="k2">(</span><span class="k1">int</span> j <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> j <span class="k3">&lt;</span> map_mbmp.h<span class="k2">;</span> j<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span>
<span class="number"> 10</span>      <span class="k2">{</span>
<span class="number"> 11</span>      c <span class="k3">=</span> <a href="http://www.allegro.cc/manual/al_get_pixel"><span class="a">al_get_pixel</span></a><span class="k2">(</span>map_mbmp, i, j<span class="k2">)</span><span class="k2">;</span>
<span class="number"> 12</span>      <span class="k1">if</span><span class="k2">(</span>c.r <span class="k3">+</span> c.g <span class="k3">+</span> c.b <span class="k3">&gt;</span> .<span class="n">1</span><span class="k2">)</span>
<span class="number"> 13</span>        <span class="k2">{</span>
<span class="number"> 14</span>        map_data<span class="k2">[</span>i<span class="k2">]</span><span class="k2">[</span>j<span class="k2">]</span> <span class="k3">=</span> <span class="k1">true</span><span class="k2">;</span> 
<span class="number"> 15</span>        <span class="k2">}</span>
<span class="number"> 16</span>      <span class="k2">}</span>
<span class="number"> 17</span>    <span class="k2">}</span>
<span class="number"> 18</span>  <span class="k2">}</span>
</div></div><p>

Removing the only non-allegro reference, map_data, has no effect on time. </p><p>I&#39;m using Linux, Ubuntu ~14.04, Allegro ~5.2.2 (recently compiled from git). 64-bit OS.</p><p>[edit] Also, just because I love inxi, here&#39;s the output:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>inxi <span class="k3">-</span>Fx
<span class="number">  2</span>System:    Host: saturn Kernel: <span class="n">4</span>.<span class="n">10</span>.<span class="n">0</span><span class="k3">-</span><span class="n">041000</span><span class="k3">-</span>generic x86_64 <span class="k2">(</span><span class="n">64</span> bit gcc: <span class="n">6</span>.<span class="n">2</span>.<span class="n">0</span><span class="k2">)</span>
<span class="number">  3</span>           Desktop: Unity <span class="n">7</span>.<span class="n">4</span>.<span class="n">5</span> <span class="k2">(</span>Gtk <span class="n">3</span>.<span class="n">18</span>.<span class="n">9</span><span class="k2">)</span> Distro: Ubuntu <span class="n">16</span>.<span class="n">04</span> xenial
<span class="number">  4</span>Machine:   System: GOOGLE <span class="k2">(</span>portable<span class="k2">)</span> product: Peppy v: <span class="n">1</span>.<span class="n">0</span>
<span class="number">  5</span>           Mobo: GOOGLE model: Peppy v: <span class="n">1</span>.<span class="n">0</span> Bios: coreboot v: <span class="n">4</span>.<span class="n">0</span><span class="k3">-</span><span class="n">6588</span><span class="k3">-</span>g4acd8ea-dirty date: <span class="n">09</span><span class="k3">/</span><span class="n">04</span><span class="k3">/</span><span class="n">2014</span>
<span class="number">  6</span>CPU:       Dual core Intel Celeron <span class="n">2955</span>U <span class="k2">(</span><span class="k3">-</span>MCP-<span class="k2">)</span> cache: <span class="n">2048</span> KB
<span class="number">  7</span>           flags: <span class="k2">(</span>lm nx sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx<span class="k2">)</span> bmips: <span class="n">5587</span>
<span class="number">  8</span>           <a href="http://www.delorie.com/djgpp/doc/libc/libc_103.html" target="_blank">clock</a> speeds: max: <span class="n">1400</span> MHz <span class="n">1</span><span class="k2">:</span> <span class="n">799</span> MHz <span class="n">2</span><span class="k2">:</span> <span class="n">799</span> MHz
<span class="number">  9</span>Graphics:  Card: Intel Haswell-ULT Integrated Graphics Controller bus-ID: <span class="n">00</span><span class="k2">:</span><span class="n">02</span>.<span class="n">0</span>
<span class="number"> 10</span>           Display Server: X.Org <span class="n">1</span>.<span class="n">18</span>.<span class="n">4</span> drivers: intel <span class="k2">(</span>unloaded: fbdev,vesa<span class="k2">)</span> Resolution: <span class="n">1366x768</span>@<span class="n">60</span>.<span class="n">00</span>hz
<span class="number"> 11</span>           GLX Renderer: Mesa DRI Intel Haswell Mobile GLX Version: <span class="n">3</span>.<span class="n">0</span> Mesa <span class="n">17</span>.<span class="n">2</span>.<span class="n">4</span> Direct Rendering: Yes
<span class="number"> 12</span>Audio:     Card-1 Intel <span class="n">8</span> Series HD Audio Controller driver: snd_hda_intel bus-ID: <span class="n">00</span><span class="k2">:</span><span class="n">1b</span>.<span class="n">0</span>
<span class="number"> 13</span>           Card-2 Intel Haswell-ULT HD Audio Controller driver: snd_hda_intel bus-ID: <span class="n">00</span><span class="k2">:</span><span class="n">03</span>.<span class="n">0</span>
<span class="number"> 14</span>           Sound: Advanced Linux Sound Architecture v: k4.10.0-041000-generic
<span class="number"> 15</span>Network:   Card: Qualcomm Atheros AR9462 Wireless Network Adapter driver: ath9k bus-ID: <span class="n">01</span><span class="k2">:</span><span class="n">00</span>.<span class="n">0</span>
<span class="number"> 16</span>           IF: wlan0 state: up mac: <span class="n">90</span><span class="k2">:</span><span class="n">48</span><span class="k2">:</span><span class="n">9a</span><span class="k2">:</span><span class="n">75</span><span class="k2">:</span>d2:f5
<span class="number"> 17</span>Drives:    HDD Total Size: <span class="n">63</span>.<span class="n">9</span>GB <span class="k2">(</span><span class="n">53</span>.<span class="n">2</span>% used<span class="k2">)</span> ID-1: <span class="k3">/</span>dev<span class="k3">/</span>sda model: KINGSTON_SNS4151 size: <span class="n">32</span>.<span class="n">0</span>GB
<span class="number"> 18</span>           ID-2: USB <span class="k3">/</span>dev<span class="k3">/</span>sdb model: Power_Saving_USB size: <span class="n">31</span>.<span class="n">9</span>GB
<span class="number"> 19</span>Partition: ID-1: <span class="k3">/</span> size: <span class="n">28</span>G used: <span class="n">23</span>G <span class="k2">(</span><span class="n">86</span>%<span class="k2">)</span> fs: ext4 dev: <span class="k3">/</span>dev<span class="k3">/</span>sda1
<span class="number"> 20</span>           ID-2: swap-1 size: <span class="n">2</span>.<span class="n">08</span>GB used: <span class="n">0</span>.<span class="n">53</span>GB <span class="k2">(</span><span class="n">25</span>%<span class="k2">)</span> fs: swap dev: <span class="k3">/</span>dev<span class="k3">/</span>sda5
<span class="number"> 21</span>RAID:      No RAID devices: <span class="k3">/</span>proc<span class="k3">/</span>mdstat, md_mod kernel module present
<span class="number"> 22</span>Sensors:   System Temperatures: cpu: <span class="n">40</span>.<span class="n">8C</span> mobo: N<span class="k3">/</span>A
<span class="number"> 23</span>           Fan Speeds <span class="k2">(</span>in rpm<span class="k2">)</span><span class="k2">:</span> cpu: N<span class="k3">/</span>A
<span class="number"> 24</span>Info:      Processes: <span class="n">255</span> Uptime: <span class="n">14</span><span class="k2">:</span><span class="n">03</span> Memory: <span class="n">1363</span>.<span class="n">1</span><span class="k3">/</span><span class="n">1872</span>.<span class="n">9</span>MB Init: systemd runlevel: <span class="n">5</span> Gcc sys: <span class="n">5</span>.<span class="n">4</span>.<span class="n">0</span>
<span class="number"> 25</span>           Client: Shell <span class="k2">(</span>bash <span class="n">4</span>.<span class="n">3</span>.<span class="n">481</span><span class="k2">)</span> inxi: <span class="n">2</span>.<span class="n">2</span>.<span class="n">35</span>
</div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Tue, 26 Dec 2017 07:11:09 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Surround your two loops with <span class="source-code"><a href="http://www.allegro.cc/manual/al_lock_bitmap"><span class="a">al_lock_bitmap</span></a></span> and <span class="source-code"><a href="http://www.allegro.cc/manual/al_unlock_bitmap"><span class="a">al_unlock_bitmap</span></a></span>. This is actually mentioned in the docs <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Tue, 26 Dec 2017 12:00:41 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>But why do memory bitmaps need locked? They&#39;re already in memory...</p><p>[edit]</p><p>Okay, with locking, it&#39;s 8 seconds.</p><p>Still... :/</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.allegro.cc/manual/al_lock_bitmap"><span class="a">al_lock_bitmap</span></a><span class="k2">(</span>map_mbmp, g.ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY<span class="k2">)</span><span class="k2">;</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Tue, 26 Dec 2017 12:10:01 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Oh, didn&#39;t notice it was already a memory bitmap, interesting that it helps! There is still quite a bit of conversion that happens even in this case and it&#39;s not really inlinable. You might get more speed by locking the bitmap and then going through the memory representations directly.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (SiegeLord)</author>
		<pubDate>Tue, 26 Dec 2017 12:59:55 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ve added a more detailed timekeeping mechanism instead of using /usr/bin/time -v ./my_program and queuing up some KEY_ESCAPE events while it loads which adds some error/variance.</p><p>I&#39;d be fine with direct bitmap access. Are there any A5 examples that expose this functionality? I had the impression that A5 had a more &quot;hands off&quot;/&quot;don&#39;t touch internals&quot; approach.</p><p>I load a bitmap that represents a per-pixel textured world, so I draw it to the screen. But I also check pixels for collisions between objects/particles and that terrain. </p><p>I have no problem having two separate data structures (one texture, one array for collision)--though I may run into issues if I start allowing deformable terrain being slow. </p><p>My only issue right now, however, is that the conversion is really slow. It takes more time to load a PNG and uncompress it, than it does to read every pixel! That can&#39;t be right! <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>Oh, I almost forgot. I am running profile mode cmake&#39;d Allegro 5, so I don&#39;t know if Allegro 5 profile is also full-debug / no optimization, so it&#39;s possible running -release will be much faster and this is due to only tons of additional debug error checking.</p><p>Thanks for the help! Hope your having a great Holiday/Christmas.</p><p>[edit] Also, while I&#39;ve got your ear. This is &quot;off-topic&quot; but still a bug AFAIK. It seems that many allegro flags don&#39;t get exposed in DAllegro. So I have to look them up with grep in Allegro 5&#39;s source code, find the flag, and then hardcode it into my D program. ALLEGRO_MEMORY_BITMAP works, but ALLEGRO_PIXEL_FORMAT_ANY and ALLEGRO_VSYNC, I definitely had to add.</p><p>[edit]</p><p>I think I tracked down the relevant code to /include/allegro5/internal/aintern_pixel.h</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">   1</span><span class="p">#define _AL_INLINE_GET_PIXEL(format, data, color, advance)                    \</span>
<span class="number">   2</span><span class="p">   do {                                                                       \ </span>
<span class="number">   3</span><span class="p">      switch (format) {                                                       \ </span>
<span class="number">   4</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ARGB_8888: {                               \ </span>
<span class="number">   5</span><span class="p">            uint32_t _gp_pixel = *(uint32_t *)(data);                         \ </span>
<span class="number">   6</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number">   7</span><span class="p">               (_gp_pixel &amp; 0x00FF0000) &gt;&gt; 16,                                \ </span>
<span class="number">   8</span><span class="p">               (_gp_pixel &amp; 0x0000FF00) &gt;&gt;  8,                                \ </span>
<span class="number">   9</span><span class="p">               (_gp_pixel &amp; 0x000000FF) &gt;&gt;  0,                                \ </span>
<span class="number">  10</span><span class="p">               (_gp_pixel &amp; 0xFF000000) &gt;&gt; 24);                               \ </span>
<span class="number">  11</span><span class="p">            if (advance)                                                      \ </span>
<span class="number">  12</span><span class="p">               data += 4;                                                     \ </span>
<span class="number">  13</span><span class="p">            break;                                                            \ </span>
<span class="number">  14</span><span class="p">         }                                                                    \ </span>
<span class="number">  15</span><span class="p">                                                                              \ </span>
<span class="number">  16</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_RGBA_8888: {                               \ </span>
<span class="number">  17</span><span class="p">            uint32_t _gp_pixel = *(uint32_t *)(data);                         \ </span>
<span class="number">  18</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number">  19</span><span class="p">               (_gp_pixel &amp; 0xFF000000) &gt;&gt; 24,                                \ </span>
<span class="number">  20</span><span class="p">               (_gp_pixel &amp; 0x00FF0000) &gt;&gt; 16,                                \ </span>
<span class="number">  21</span><span class="p">               (_gp_pixel &amp; 0x0000FF00) &gt;&gt;  8,                                \ </span>
<span class="number">  22</span><span class="p">               (_gp_pixel &amp; 0x000000FF) &gt;&gt;  0);                               \ </span>
<span class="number">  23</span><span class="p">            if (advance)                                                      \ </span>
<span class="number">  24</span><span class="p">               data += 4;                                                     \ </span>
<span class="number">  25</span><span class="p">            break;                                                            \ </span>
<span class="number">  26</span><span class="p">         }                                                                    \ </span>
<span class="number">  27</span><span class="p">                                                                              \ </span>
<span class="number">  28</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ARGB_4444: {                               \ </span>
<span class="number">  29</span><span class="p">            uint16_t _gp_pixel = *(uint16_t *)(data);                         \ </span>
<span class="number">  30</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number">  31</span><span class="p">               _al_rgb_scale_4[(_gp_pixel &amp; 0x0F00) &gt;&gt; 8],                       \ </span>
<span class="number">  32</span><span class="p">               _al_rgb_scale_4[(_gp_pixel &amp; 0x00F0) &gt;&gt; 4],                       \ </span>
<span class="number">  33</span><span class="p">               _al_rgb_scale_4[(_gp_pixel &amp; 0x000F)],                            \ </span>
<span class="number">  34</span><span class="p">               _al_rgb_scale_4[(_gp_pixel &amp; 0xF000) &gt;&gt;  12]);                    \ </span>
<span class="number">  35</span><span class="p">            if (advance)                                                      \ </span>
<span class="number">  36</span><span class="p">               data += 2;                                                     \ </span>
<span class="number">  37</span><span class="p">            break;                                                            \ </span>
<span class="number">  38</span><span class="p">         }                                                                    \ </span>
<span class="number">  39</span><span class="p">                                                                              \ </span>
<span class="number">  40</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_RGB_888: {                                 \ </span>
<span class="number">  41</span><span class="p">            uint32_t _gp_pixel = READ3BYTES(data);                            \ </span>
<span class="number">  42</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number">  43</span><span class="p">               (_gp_pixel &amp; 0xFF0000) &gt;&gt; 16,                                  \ </span>
<span class="number">  44</span><span class="p">               (_gp_pixel &amp; 0x00FF00) &gt;&gt;  8,                                  \ </span>
<span class="number">  45</span><span class="p">               (_gp_pixel &amp; 0x0000FF) &gt;&gt;  0,                                  \ </span>
<span class="number">  46</span><span class="p">               255);                                                          \ </span>
<span class="number">  47</span><span class="p">            if (advance)                                                      \ </span>
<span class="number">  48</span><span class="p">               data += 3;                                                     \ </span>
<span class="number">  49</span><span class="p">            break;                                                            \ </span>
<span class="number">  50</span><span class="p">         }                                                                    \ </span>
<span class="number">  51</span><span class="p">                                                                              \ </span>
<span class="number">  52</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_RGB_565: {                                 \ </span>
<span class="number">  53</span><span class="p">            uint16_t _gp_pixel = *(uint16_t *)(data);                         \ </span>
<span class="number">  54</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number">  55</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0xF800) &gt;&gt; 11],                      \ </span>
<span class="number">  56</span><span class="p">               _al_rgb_scale_6[(_gp_pixel &amp; 0x07E0) &gt;&gt; 5],                       \ </span>
<span class="number">  57</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x001F)],                            \ </span>
<span class="number">  58</span><span class="p">               255);                                                          \ </span>
<span class="number">  59</span><span class="p">            if (advance)                                                      \ </span>
<span class="number">  60</span><span class="p">               data += 2;                                                     \ </span>
<span class="number">  61</span><span class="p">            break;                                                            \ </span>
<span class="number">  62</span><span class="p">         }                                                                    \ </span>
<span class="number">  63</span><span class="p">                                                                              \ </span>
<span class="number">  64</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_RGB_555: {                                 \ </span>
<span class="number">  65</span><span class="p">            uint16_t _gp_pixel = *(uint16_t *)(data);                         \ </span>
<span class="number">  66</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number">  67</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x7C00) &gt;&gt; 10],                      \ </span>
<span class="number">  68</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x03E0) &gt;&gt; 5],                       \ </span>
<span class="number">  69</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x001F)],                            \ </span>
<span class="number">  70</span><span class="p">               255);                                                          \ </span>
<span class="number">  71</span><span class="p">            if (advance)                                                      \ </span>
<span class="number">  72</span><span class="p">               data += 2;                                                     \ </span>
<span class="number">  73</span><span class="p">            break;                                                            \ </span>
<span class="number">  74</span><span class="p">         }                                                                    \ </span>
<span class="number">  75</span><span class="p">                                                                              \ </span>
<span class="number">  76</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_RGBA_5551: {                               \ </span>
<span class="number">  77</span><span class="p">            uint16_t _gp_pixel = *(uint16_t *)(data);                         \ </span>
<span class="number">  78</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number">  79</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0xF800) &gt;&gt; 11],                      \ </span>
<span class="number">  80</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x07C0) &gt;&gt; 6],                       \ </span>
<span class="number">  81</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x003E) &gt;&gt; 1],                       \ </span>
<span class="number">  82</span><span class="p">               _al_rgb_scale_1[_gp_pixel &amp; 1]);                                                          \ </span>
<span class="number">  83</span><span class="p">            if (advance)                                                      \ </span>
<span class="number">  84</span><span class="p">               data += 2;                                                     \ </span>
<span class="number">  85</span><span class="p">            break;                                                            \ </span>
<span class="number">  86</span><span class="p">         }                                                                    \ </span>
<span class="number">  87</span><span class="p">                                                                              \ </span>
<span class="number">  88</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ARGB_1555: {                               \ </span>
<span class="number">  89</span><span class="p">            uint16_t _gp_pixel = *(uint16_t *)(data);                         \ </span>
<span class="number">  90</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number">  91</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x7C00) &gt;&gt; 10],                      \ </span>
<span class="number">  92</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x03E0) &gt;&gt; 5],                       \ </span>
<span class="number">  93</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x001F)],                            \ </span>
<span class="number">  94</span><span class="p">               _al_rgb_scale_1[(_gp_pixel &amp; 0x8000) &gt;&gt; 15]);                  \ </span>
<span class="number">  95</span><span class="p">            if (advance)                                                      \ </span>
<span class="number">  96</span><span class="p">               data += 2;                                                     \ </span>
<span class="number">  97</span><span class="p">            break;                                                            \ </span>
<span class="number">  98</span><span class="p">         }                                                                    \ </span>
<span class="number">  99</span><span class="p">                                                                              \ </span>
<span class="number"> 100</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ABGR_8888: {                               \ </span>
<span class="number"> 101</span><span class="p">            uint32_t _gp_pixel = *(uint32_t *)(data);                         \ </span>
<span class="number"> 102</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number"> 103</span><span class="p">               (_gp_pixel &amp; 0x000000FF) &gt;&gt;  0,                                \ </span>
<span class="number"> 104</span><span class="p">               (_gp_pixel &amp; 0x0000FF00) &gt;&gt;  8,                                \ </span>
<span class="number"> 105</span><span class="p">               (_gp_pixel &amp; 0x00FF0000) &gt;&gt; 16,                                \ </span>
<span class="number"> 106</span><span class="p">               (_gp_pixel &amp; 0xFF000000) &gt;&gt; 24);                               \ </span>
<span class="number"> 107</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 108</span><span class="p">               data += 4;                                                     \ </span>
<span class="number"> 109</span><span class="p">            break;                                                            \ </span>
<span class="number"> 110</span><span class="p">         }                                                                    \ </span>
<span class="number"> 111</span><span class="p">                                                                              \ </span>
<span class="number"> 112</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_XBGR_8888: {                               \ </span>
<span class="number"> 113</span><span class="p">            uint32_t _gp_pixel = *(uint32_t *)(data);                         \ </span>
<span class="number"> 114</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number"> 115</span><span class="p">               (_gp_pixel &amp; 0x000000FF) &gt;&gt;  0,                                \ </span>
<span class="number"> 116</span><span class="p">               (_gp_pixel &amp; 0x0000FF00) &gt;&gt;  8,                                \ </span>
<span class="number"> 117</span><span class="p">               (_gp_pixel &amp; 0x00FF0000) &gt;&gt; 16,                                \ </span>
<span class="number"> 118</span><span class="p">               255);                                                          \ </span>
<span class="number"> 119</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 120</span><span class="p">               data += 4;                                                     \ </span>
<span class="number"> 121</span><span class="p">            break;                                                            \ </span>
<span class="number"> 122</span><span class="p">         }                                                                    \ </span>
<span class="number"> 123</span><span class="p">                                                                              \ </span>
<span class="number"> 124</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_BGR_888: {                                 \ </span>
<span class="number"> 125</span><span class="p">            uint32_t _gp_pixel = READ3BYTES(data);                            \ </span>
<span class="number"> 126</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number"> 127</span><span class="p">               (_gp_pixel &amp; 0x000000FF) &gt;&gt;  0,                                \ </span>
<span class="number"> 128</span><span class="p">               (_gp_pixel &amp; 0x0000FF00) &gt;&gt;  8,                                \ </span>
<span class="number"> 129</span><span class="p">               (_gp_pixel &amp; 0x00FF0000) &gt;&gt; 16,                                \ </span>
<span class="number"> 130</span><span class="p">               255);                                                          \ </span>
<span class="number"> 131</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 132</span><span class="p">               data += 4;                                                     \ </span>
<span class="number"> 133</span><span class="p">            break;                                                            \ </span>
<span class="number"> 134</span><span class="p">         }                                                                    \ </span>
<span class="number"> 135</span><span class="p">                                                                              \ </span>
<span class="number"> 136</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_BGR_565: {                                 \ </span>
<span class="number"> 137</span><span class="p">            uint16_t _gp_pixel = *(uint16_t *)(data);                         \ </span>
<span class="number"> 138</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number"> 139</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x001F)],                            \ </span>
<span class="number"> 140</span><span class="p">               _al_rgb_scale_6[(_gp_pixel &amp; 0x07E0) &gt;&gt; 5],                       \ </span>
<span class="number"> 141</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0xF800) &gt;&gt; 11],                      \ </span>
<span class="number"> 142</span><span class="p">               255);                                                          \ </span>
<span class="number"> 143</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 144</span><span class="p">               data += 2;                                                     \ </span>
<span class="number"> 145</span><span class="p">            break;                                                            \ </span>
<span class="number"> 146</span><span class="p">         }                                                                    \ </span>
<span class="number"> 147</span><span class="p">                                                                              \ </span>
<span class="number"> 148</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_BGR_555: {                                 \ </span>
<span class="number"> 149</span><span class="p">            uint16_t _gp_pixel = *(uint16_t *)(data);                         \ </span>
<span class="number"> 150</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number"> 151</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x001F)],                            \ </span>
<span class="number"> 152</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x03E0) &gt;&gt; 5],                       \ </span>
<span class="number"> 153</span><span class="p">               _al_rgb_scale_5[(_gp_pixel &amp; 0x7C00) &gt;&gt; 10],                      \ </span>
<span class="number"> 154</span><span class="p">               255);                                                          \ </span>
<span class="number"> 155</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 156</span><span class="p">               data += 2;                                                     \ </span>
<span class="number"> 157</span><span class="p">            break;                                                            \ </span>
<span class="number"> 158</span><span class="p">         }                                                                    \ </span>
<span class="number"> 159</span><span class="p">                                                                              \ </span>
<span class="number"> 160</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_RGBX_8888: {                               \ </span>
<span class="number"> 161</span><span class="p">            uint32_t _gp_pixel = *(uint32_t *)(data);                         \ </span>
<span class="number"> 162</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number"> 163</span><span class="p">               (_gp_pixel &amp; 0xFF000000) &gt;&gt; 24,                                \ </span>
<span class="number"> 164</span><span class="p">               (_gp_pixel &amp; 0x00FF0000) &gt;&gt; 16,                                \ </span>
<span class="number"> 165</span><span class="p">               (_gp_pixel &amp; 0x0000FF00) &gt;&gt;  8,                                \ </span>
<span class="number"> 166</span><span class="p">               255);                                                          \ </span>
<span class="number"> 167</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 168</span><span class="p">               data += 4;                                                     \ </span>
<span class="number"> 169</span><span class="p">            break;                                                            \ </span>
<span class="number"> 170</span><span class="p">         }                                                                    \ </span>
<span class="number"> 171</span><span class="p">                                                                              \ </span>
<span class="number"> 172</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_XRGB_8888: {                               \ </span>
<span class="number"> 173</span><span class="p">            uint32_t _gp_pixel = *(uint32_t *)(data);                         \ </span>
<span class="number"> 174</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number"> 175</span><span class="p">               (_gp_pixel &amp; 0x00FF0000) &gt;&gt; 16,                                \ </span>
<span class="number"> 176</span><span class="p">               (_gp_pixel &amp; 0x0000FF00) &gt;&gt;  8,                                \ </span>
<span class="number"> 177</span><span class="p">               (_gp_pixel &amp; 0x000000FF),                                      \ </span>
<span class="number"> 178</span><span class="p">               255);                                                          \ </span>
<span class="number"> 179</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 180</span><span class="p">               data += 4;                                                     \ </span>
<span class="number"> 181</span><span class="p">            break;                                                            \ </span>
<span class="number"> 182</span><span class="p">         }                                                                    \ </span>
<span class="number"> 183</span><span class="p">                                                                              \ </span>
<span class="number"> 184</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ABGR_F32: {                                \ </span>
<span class="number"> 185</span><span class="p">            float *f = (float *)data;                                         \ </span>
<span class="number"> 186</span><span class="p">            color.r = f[0];                                                   \ </span>
<span class="number"> 187</span><span class="p">            color.g = f[1];                                                   \ </span>
<span class="number"> 188</span><span class="p">            color.b = f[2];                                                   \ </span>
<span class="number"> 189</span><span class="p">            color.a = f[3];                                                   \ </span>
<span class="number"> 190</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 191</span><span class="p">               data += 4 * sizeof(float);                                     \ </span>
<span class="number"> 192</span><span class="p">            break;                                                            \ </span>
<span class="number"> 193</span><span class="p">         }                                                                    \ </span>
<span class="number"> 194</span><span class="p">                                                                              \ </span>
<span class="number"> 195</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE: {                            \ </span>
<span class="number"> 196</span><span class="p">            uint8_t *p = (uint8_t *)data;                                     \ </span>
<span class="number"> 197</span><span class="p">            _AL_MAP_RGBA(color, *p, *(p + 1), *(p + 2), *(p + 3));            \ </span>
<span class="number"> 198</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 199</span><span class="p">               data += 4;                                                     \ </span>
<span class="number"> 200</span><span class="p">            break;                                                            \ </span>
<span class="number"> 201</span><span class="p">         }                                                                    \ </span>
<span class="number"> 202</span><span class="p">                                                                              \ </span>
<span class="number"> 203</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_RGBA_4444: {                               \ </span>
<span class="number"> 204</span><span class="p">            uint16_t _gp_pixel = *(uint16_t *)(data);                         \ </span>
<span class="number"> 205</span><span class="p">            _AL_MAP_RGBA(color,                                               \ </span>
<span class="number"> 206</span><span class="p">               _al_rgb_scale_4[(_gp_pixel &amp; 0xF000) &gt;&gt; 12],                   \ </span>
<span class="number"> 207</span><span class="p">               _al_rgb_scale_4[(_gp_pixel &amp; 0x0F00) &gt;&gt; 8],                    \ </span>
<span class="number"> 208</span><span class="p">               _al_rgb_scale_4[(_gp_pixel &amp; 0x00F0) &gt;&gt; 4],                    \ </span>
<span class="number"> 209</span><span class="p">               _al_rgb_scale_4[(_gp_pixel &amp; 0x000F)]);                        \ </span>
<span class="number"> 210</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 211</span><span class="p">               data += 2;                                                     \ </span>
<span class="number"> 212</span><span class="p">            break;                                                            \ </span>
<span class="number"> 213</span><span class="p">         }                                                                    \ </span>
<span class="number"> 214</span><span class="p">                                                                              \ </span>
<span class="number"> 215</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_SINGLE_CHANNEL_8: {                        \ </span>
<span class="number"> 216</span><span class="p">            uint8_t c = *(uint8_t *)(data);                                   \ </span>
<span class="number"> 217</span><span class="p">            _AL_MAP_RGBA(color, c, c, c, 255);                                \ </span>
<span class="number"> 218</span><span class="p">            if (advance)                                                      \ </span>
<span class="number"> 219</span><span class="p">               data += 2;                                                     \ </span>
<span class="number"> 220</span><span class="p">            break;                                                            \ </span>
<span class="number"> 221</span><span class="p">         }                                                                    \ </span>
<span class="number"> 222</span><span class="p">                                                                              \ </span>
<span class="number"> 223</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY:                                       \ </span>
<span class="number"> 224</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA:                              \ </span>
<span class="number"> 225</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA:                            \ </span>
<span class="number"> 226</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA:                           \ </span>
<span class="number"> 227</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA:                           \ </span>
<span class="number"> 228</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA:                         \ </span>
<span class="number"> 229</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA:                           \ </span>
<span class="number"> 230</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA:                           \ </span>
<span class="number"> 231</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA:                         \ </span>
<span class="number"> 232</span><span class="p">            ALLEGRO_ERROR("INLINE_GET got fake pixel format: %d\n", format); \ </span>
<span class="number"> 233</span><span class="p">            abort();                                                          \ </span>
<span class="number"> 234</span><span class="p">            break;                                                            \ </span>
<span class="number"> 235</span><span class="p">                                                                              \ </span>
<span class="number"> 236</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT1:                                 \ </span>
<span class="number"> 237</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT3:                                 \ </span>
<span class="number"> 238</span><span class="p">         case ALLEGRO_PIXEL_FORMAT_COMPRESSED_RGBA_DXT5:                                 \ </span>
<span class="number"> 239</span><span class="p">            ALLEGRO_ERROR("INLINE_GET got compressed format: %d\n", format); \ </span>
<span class="number"> 240</span><span class="p">            abort();                                                          \ </span>
<span class="number"> 241</span><span class="p">            break;                                                            \ </span>
<span class="number"> 242</span><span class="p">                                                                              \ </span>
<span class="number"> 243</span><span class="p">         case ALLEGRO_NUM_PIXEL_FORMATS:                                      \ </span>
<span class="number"> 244</span><span class="p">         default:                                                             \ </span>
<span class="number"> 245</span><span class="p">            ALLEGRO_ERROR("INLINE_GET got non pixel format: %d\n", format); \ </span>
<span class="number"> 246</span><span class="p">            abort();                                                          \ </span>
<span class="number"> 247</span><span class="p">            break;                                                            \ </span>
<span class="number"> 248</span><span class="p">      }                                                                       \ </span>
<span class="number"> 249</span><span class="p">   } while (0) </span>
</div></div><p>

Perhaps as long as I ensure the bitmap format, I can just use the relevant case in here. No wonder getpixel is so slow! There&#39;s branches and branches and cases and cases! Making sure it&#39;s locked, and if not, what to do. Making sure it&#39;s the right format. Whether it&#39;s a sub-bitmap or not. Clipping. Goodness!</p><p>[edit]</p><p><b>It&#39;s not allegro at all!!!</b></p><p>DMD&#39;s profiling switch is EXPLODING the call time. Timing just the bitmap -&gt; array function, without --profile it takes 1.03 seconds! With --profile, it takes 6 seconds. --profile-gc (garbage collections) doesn&#39;t affect it noticably, just --profile. </p><p>It&#39;s possible because al_get_pixel is doing tons of really short functions, the tracing functions themselves become a huge overhead. I&#39;m going to do a follow up on dlang.org forums. I&#39;m also going to test LDC&#39;s profiling which (AFAIK) uses completely different profiling functions/instrumentation.</p><p>One second to process 15 MB of data with all those extra clipping/locking/pixel-format checks on a humble Celeron netbook is not surprising or unreasonable. I&#39;m probably going to move forward with a specific internal al_get_pixel function or code snippet, as well as follow up with the profiling.</p><p>The clue came to me when I was running Valgrind tests on it. I kept getting functions called &quot;trace&quot; taking large amounts of time and they were embedded in allegro functions/etc. And then the dumb revelation finally dawned on me. &quot;DUH! I had --profile on!&quot; I&#39;ve been coding with it on and never had any problem with it. But I think maybe this specific use case explodes the overhead of whatever criterea/method/algorithm they&#39;re using for tracing in DMD.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Chris Katko)</author>
		<pubDate>Tue, 26 Dec 2017 17:05:38 +0000</pubDate>
	</item>
</rss>
