<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>&#60;&#60; shiftedbits &#187; Programming</title>
	<atom:link href="http://shiftedbits.org/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://shiftedbits.org</link>
	<description>Shift those bits. C'mon, shift em!</description>
	<lastBuildDate>Sun, 19 Apr 2009 19:42:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>mach_absolute_time on the iPhone</title>
		<link>http://shiftedbits.org/2008/10/01/mach_absolute_time-on-the-iphone/</link>
		<comments>http://shiftedbits.org/2008/10/01/mach_absolute_time-on-the-iphone/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 16:22:47 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/?p=17</guid>
		<description><![CDATA[As programmers on OS X are well aware, the units of mach_absolute_time() have been nanoseconds since 10.2, although this was only documented since 10.5. As the iPhone runs a slimmed down version of OS X, I thought it reasonable that the units would remain the same on the device.
Not so.
On the iPhone, the timebase is [...]]]></description>
			<content:encoded><![CDATA[<p>As programmers on OS X are well aware, the units of <code>mach_absolute_time()</code> have been nanoseconds since 10.2, although this was only documented since 10.5. As the iPhone runs a slimmed down version of OS X, I thought it reasonable that the units would remain the same on the device.</p>
<p>Not so.</p>
<p>On the iPhone, the timebase is different. The <code>mach_timebase_info</code> structure contains a numerator and denominator that can be used to convert between the result returned by <code>mach_absolute_time()</code> and nanoseconds. On OS X Leopard, the numerator and denominator are both 1, meaning that the units are already in nanoseconds. On OS X iPhone, the numerator is 1,000,000,000, while the denominator is 6,000,000. Thus, every unit of absolute time on the iPhone is 166.67 nanoseconds.</p>
<p>So if you&#8217;re trying to get some timing from the iPhone using <code>mach_absolute_time()</code> and seeing times that indicate <strong>faster</strong> results on the iPhone, (not that this happened to me&#8230;), make sure to account for the difference in timebase.</p>
<p>Here&#8217;s the code for conversion between the iPhone&#8217;s <code>mach_absolute_time()</code> and nanoseconds:</p>
<pre>/* Get the timebase info */
mach_timebase_info_data_t info;
mach_timebase_info(&#038;info);

uint64_t start = mach_absolute_time();

/* Do some code */

uint64_t duration = mach_absolute_time() - start;

/* Convert to nanoseconds */
duration *= info.numer;
duration /= info.denom;

/* Log the time */
NSLog(@"My amazing code took %lld nanoseconds!", duration);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2008/10/01/mach_absolute_time-on-the-iphone/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Key Value Observing Improvements v1.2.2</title>
		<link>http://shiftedbits.org/2008/09/13/key-value-observing-improvements-v122/</link>
		<comments>http://shiftedbits.org/2008/09/13/key-value-observing-improvements-v122/#comments</comments>
		<pubDate>Sat, 13 Sep 2008 23:50:29 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/?p=50</guid>
		<description><![CDATA[Quick bug fix update:
1.2.2 Fixes a crash due to a missing implementation of __KVOAdditions__dealloc__original__ on NSObject.
1.2.1 now runs on the iPhone.
The new updates are in SVN at http://svn.shiftedbits.org/public/KVOAdditions/trunk and tagged at http://svn.shiftedbits.org/public/KVOAdditions/tags/1.2.2
]]></description>
			<content:encoded><![CDATA[<p>Quick bug fix update:</p>
<p>1.2.2 Fixes a crash due to a missing implementation of __KVOAdditions__dealloc__original__ on NSObject.</p>
<p>1.2.1 now runs on the iPhone.</p>
<p>The new updates are in SVN at <code>http://svn.shiftedbits.org/public/KVOAdditions/trunk</code> and tagged at <code>http://svn.shiftedbits.org/public/KVOAdditions/tags/1.2.2</code></p>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2008/09/13/key-value-observing-improvements-v122/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Key Value Observing Improvements v1.2</title>
		<link>http://shiftedbits.org/2008/09/03/key-value-observing-improvements-v12/</link>
		<comments>http://shiftedbits.org/2008/09/03/key-value-observing-improvements-v12/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 05:35:57 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Leopard]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/?p=46</guid>
		<description><![CDATA[Hot on the heels of the 1.1 bug fix release comes version a freshly rewritten 1.2 with API cleanup, bug fixes, and a great new feature.
Lately, I&#8217;ve been using observers to allow an object to observe changes to its own properties. This means I don&#8217;t have to override the setter method (I&#8217;m using synthesized properties) [...]]]></description>
			<content:encoded><![CDATA[<p>Hot on the heels of the 1.1 bug fix release comes version a freshly rewritten 1.2 with API cleanup, bug fixes, and a great new feature.</p>
<p>Lately, I&#8217;ve been using observers to allow an object to observe changes to its own properties. This means I don&#8217;t have to override the setter method (I&#8217;m using synthesized properties) and the observation is managed the same way that it would be externally. The current KVO implementation (at least, in non-GC land,) however, doesn&#8217;t allow you to remove observations from yourself in your -dealloc method. This is due to the way KVO works, by interposing a KVODeallocate function before your -dealloc method. It expects that all observers of the object have been removed at this point, and warns if they are not. This is, of course, blindingly annoying &#8212; you now have to create a method that gets called on your objects by their owner before they dealloc so that they can remove their observers.</p>
<p>To fix this, I&#8217;ve done a little interposing of my own, putting in another dealloc method before KVODealloc that will remove self observers and call a -KVODealloc method on the deallocating observer object before KVODeallocate is called. If you don&#8217;t want automatic removal, simply return NO from +automaticallyRemoveSelfObservations on the class of your choice.</p>
<p>The new updates are in SVN at <code>http://svn.shiftedbits.org/public/KVOAdditions/trunk</code> and tagged at <code>http://svn.shiftedbits.org/public/KVOAdditions/tags/1.2</code><br />
<span id="more-46"></span><br />
Version 1.2 also adds new methods for removing an observer that include a selector parameter.</p>
<p><code>NSObject:</code></p>
<pre>- (void)removeObserver:(NSObject *)observer
            forKeyPath:(NSString *)keyPath
              selector:(SEL)selector;
</pre>
<p><code>NSArray:</code></p>
<pre>- (void)removeObserver:(NSObject *)observer
  fromObjectsAtIndexes:(NSIndexSet *)indexes
            forKeyPath:(NSString *)keyPath
              selector:(SEL)selector;
</pre>
<p>The selector is now considered a unique part of the observation, and so a class can observe a single property on a single object using multiple selectors. This allows a class and its subclass to avoid collisions when observing a single object.</p>
<p>The <code>-removeObserver:forKeyPath:</code> method now no longer removes selector-based observers.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2008/09/03/key-value-observing-improvements-v12/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Key Value Observing Improvements</title>
		<link>http://shiftedbits.org/2008/07/24/key-value-observing-improvements/</link>
		<comments>http://shiftedbits.org/2008/07/24/key-value-observing-improvements/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 08:26:28 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/?p=23</guid>
		<description><![CDATA[Key value observing is quite a useful tool, no doubt about it. But it has a singularly annoying manner of informing the observer of a change. The -[NSObject observeValueForKeyPath:ofObject:change:context:] method is sent to the observer when a change occurs. It&#8217;s up to the implementor to parse the `change&#8217; dictionary to figure out what changed.
When I [...]]]></description>
			<content:encoded><![CDATA[<p>Key value observing is quite a useful tool, no doubt about it. But it has a singularly annoying manner of informing the observer of a change. The <code>-[NSObject observeValueForKeyPath:ofObject:change:context:]</code> method is sent to the observer when a change occurs. It&#8217;s up to the implementor to parse the `change&#8217; dictionary to figure out what changed.</p>
<p>When I use observers, I usually want a method called on my class when a change occurs, similar to target/action with UI elements. So my <code>-[NSObject observeValueForKeyPath:ofObject:change:context:]</code> is basically a set of if&#8217;s for each key I&#8217;m observing that calls the appropriate method.</p>
<p>This turns out to be pretty nasty, especially when you have multiple classes in a hierarchy implementing the method. It wasn&#8217;t obvious to me that I needed to call super in this method. Thirty minutes of debugging later, and I was convinced there had to be a better way of doing it.</p>
<p>To this effort, I present two new APIs. To NSObject, I add <code>-[NSObject addObserver:forKeyPath:options:selector:]</code> and to NSArray, <code>-[NSArray addObserver:toObjectsAtIndexes:forKeyPath:options:selector]</code>. The code is <a href="/static/KVOAdditions.zip">available here</a>, or keep reading for the details.</p>
<p><strong>Update 1.1: Two critical bug fixes</strong>. Please update to the new version if you have the old one. Also, anonymous svn is now available if you want to use an external. http://svn.shiftedbits.org/public/KVOAdditions/trunk.<span id="more-23"></span></p>
<p><code>NSObject:</code></p>
<pre>@interface NSObject (KVOAdditions)

- (void)addObserver:(NSObject *)observer
         forKeyPath:(NSString *)keyPath
            options:(NSKeyValueObservingOptions)options
           selector:(SEL)aSelector;

@end
</pre>
<p><code>NSArray:</code></p>
<pre>@interface NSArray (KVOAdditions)

- (void)addObserver:(NSObject *)observer
 toObjectsAtIndexes:(NSIndexSet *)indexes
         forKeyPath:(NSString *)keyPath
            options:(NSKeyValueObservingOptions)options
           selector:(SEL)aSelector;

@end
</pre>
<p>These allow you to observe a keyPath on an object and receive a message to the designated selector when the change occurs. Furthermore, the selector can have four different signatures that allow for different levels of information to be received. These selector formats are as follows:</p>
<pre>/* Receive no information about the change */
- (void)valueDidChange;

/* Receive the raw change dictionary */
- (void)valueDidChange:(NSDictionary *)change;

/* If the observing options include either
 * NSKeyValueObservingOptionOld or NSKeyValueObservingOptionNew,
 * receive the old and new values */
- (void)valueDidChange:(id)old newValue:(id)new;

/* If the observing options include either
 * NSKeyValueObservingOptionOld or NSKeyValueObservingOptionNew,
 * receive the old and new values */
- (void)valueDidChange:(id)old newValue:(id)new prior:(BOOL)isPrior;
</pre>
<p>Feedback on these APIs, including suggestions and criticism (and even bugs!) are of course welcome. </p>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2008/07/24/key-value-observing-improvements/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SSE Optimized Compositing</title>
		<link>http://shiftedbits.org/2008/01/29/sse-optimized-compositing/</link>
		<comments>http://shiftedbits.org/2008/01/29/sse-optimized-compositing/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 06:08:46 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/2008/01/29/sse-optimized-compositing/</guid>
		<description><![CDATA[As part of a graphics API I&#8217;ve been working on (for my own use, it&#8217;s hardly ready for production,) I decided to try learning SSE optimization by making the compositing routine faster.
I came up with an implementation which, according to my tests, is 3-5X faster than the non-optimized version. The optimized version below composites a [...]]]></description>
			<content:encoded><![CDATA[<p>As part of a graphics API I&#8217;ve been working on (for my own use, it&#8217;s hardly ready for production,) I decided to try learning SSE optimization by making the compositing routine faster.</p>
<p>I came up with an implementation which, according to my tests, is 3-5X faster than the non-optimized version. The optimized version below composites a single color starting at a destination pixel buffer for a specified run of pixels. It uses source over compositing on a RGBA, 8bpc, integer pixel buffer.</p>
<p>The optimized version is presented below:</p>
<p><span id="more-14"></span></p>
<pre>
static __m128i zero =
        _mm_set_epi32(0x0, 0x0, 0x0, 0x0);
static __m128i one =
        _mm_set_epi32(0x00010001U, 0x00010001U, 0x00010001U, 0x00010001U);
static __m128i mask1 =
        _mm_set_epi32(0x00FF00FFU, 0x00FF00FFU, 0x00FF00FFU, 0x00FF00FFU);
static __m128i mask2 =
        _mm_set_epi32(0xFF00FF00U, 0xFF00FF00U, 0xFF00FF00U, 0xFF00FF00U);

if (_comp[3] == 255) {
    /* We're compositing a fully opaque pixel, just copy onto the destination */

    unsigned int *dst = (unsigned int *)_dst;

    /* The pixel offset from dst */
    size_t i = 0;

    /* The number of quad-pixels processed */
    size_t j = 0;

    /* Leading 0..3 pixels */
    while (((intptr_t)(dst+i) &#038; (intptr_t)0xF) != 0) {
        *(dst + i) = *(unsigned int *)_comp;
        i++; run--;
    }

    /* Start at the pixel i */
    __m128i *mdst = (__m128i *)(dst + i);

    /* Set 4 pixel chunks */
    for (j = 0; j < (run>>2); j++) {
        _mm_prefetch(mdst+1, _MM_HINT_T0);
        _mm_store_si128(mdst++, _src);
    }

    /* If we couldn't get all of the run in 4 pixel chunks, get them now */
    for (size_t k = 0; k < run % 4; k++) {
        *(dst + i + k + (j<&lt;2)) = *(unsigned int *)_comp;
    }
} else {
    /* We need full composition as this pixel has transparency */

    unsigned char *dst = (unsigned char *)_dst;

    /* char offset from dst */
    size_t i = 0;

    /* Quad-pixels processed */
    size_t j = 0;

    /* get the non-aligned starting 0..3 pixels */
    while (((intptr_t)(dst+i) &#038; (intptr_t)0xF) != 0) {
        dst[0+i] = _comp[0] + dst[0+i] -
            (dst[0+i] > 0? ((((unsigned short)dst[0+i] * _comp[3]) >> 8) + 1) : 0); //R
        dst[1+i] = _comp[1] + dst[1+i] -
            (dst[1+i] > 0? ((((unsigned short)dst[1+i] * _comp[3]) >> 8) + 1) : 0); //G
        dst[2+i] = _comp[2] + dst[2+i] -
            (dst[2+i] > 0? ((((unsigned short)dst[2+i] * _comp[3]) >> 8) + 1) : 0); //B
        dst[3+i] = _comp[3] + dst[3+i] -
            (dst[3+i] > 0? ((((unsigned short)dst[3+i] * _comp[3]) >> 8) + 1) : 0); //A
        i += 4; run--;
    }

    /* Load in 2 pixels */
    __m128i *mdst = (__m128i *)(dst+i);
    __m128i d, d1, d2, res;
    for (j; j < (run>>2); j++) {
        /* Load 4 pixels */
        d = _mm_load_si128(mdst);

        /* Take chars 0,2,4,6,8,10,12,14 and composite */
        d1 = _mm_and_si128(d, mask1);
        d1 = _mm_add_epi16(_mm_subs_epi16(d1, _mm_add_epi16(
                    _mm_srli_epi16(_mm_mullo_epi16(d1, _c3), 8),
                    _mm_and_si128(_mm_cmpgt_epi16(d1, zero), one))), _ce);

        /* Take chars 1,3,5,7,9,11,13,15 and composite */
        d2 = _mm_srli_epi16(_mm_and_si128(d, mask2), 8);

        /* prefetch the next 4 pixels */
        _mm_prefetch(mdst+1, _MM_HINT_T0);

        d2 = _mm_add_epi16(_mm_subs_epi16(d2, _mm_add_epi16(
                    _mm_srli_epi16(_mm_mullo_epi16(d2, _c3), 8),
                    _mm_and_si128(_mm_cmpgt_epi16(d2, zero), one))), _co);

        /* shift odd chars (d2) to high 8 bits and or with d1 */
        res = _mm_or_si128(d1, _mm_slli_epi16(d2, 8));

        /* Store 4 pixels */
        _mm_store_si128(mdst, res);

        mdst++;
    }

    // Get the trailing 0..3 pixels
    dst += i + (j< &lt;4);
    for (size_t k = 0; k < (run % 4) * 4; k+=4) {
        dst[0+k] = _comp[0] + dst[0+k] -
            (dst[0+k] > 0? ((((unsigned short)dst[0+k] * _comp[3]) >> 8) + 1) : 0); //R
        dst[1+k] = _comp[1] + dst[1+k] -
            (dst[1+k] > 0? ((((unsigned short)dst[1+k] * _comp[3]) >> 8) + 1) : 0); //G
        dst[2+k] = _comp[2] + dst[2+k] -
            (dst[2+k] > 0? ((((unsigned short)dst[2+k] * _comp[3]) >> 8) + 1) : 0); //B
        dst[3+k] = _comp[3] + dst[3+k] -
            (dst[3+k] > 0? ((((unsigned short)dst[3+k] * _comp[3]) >> 8) + 1) : 0); //A
    }
}
</pre>
<p>_c3 is a vector composed solely of the alpha value of the color.<br />
_ce is a vector composed of pairs of the red and blue components.<br />
_co is a vector composed of pairs of the green and alpha components.<br />
_src is the start address of the pixel buffer.</p>
<p>_c3, _ce, _co, and _src are set from the following function:</p>
<pre>
unsigned short r = _comp[0], g = _comp[1], b = _comp[2], a = _comp[3];
_c3 = _mm_setr_epi16(a, a, a, a, a, a, a, a);
_ce = _mm_setr_epi16(r, b, r, b, r, b, r, b);
_co = _mm_setr_epi16(g, a, g, a, g, a, g, a);

_src = _mm_set_epi32(*(int*)_comp, *(int*)_comp, *(int*)_comp, *(int*)_comp);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2008/01/29/sse-optimized-compositing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Transparency Layer Slowdowns</title>
		<link>http://shiftedbits.org/2008/01/22/transparency-layer-slowdowns/</link>
		<comments>http://shiftedbits.org/2008/01/22/transparency-layer-slowdowns/#comments</comments>
		<pubDate>Tue, 22 Jan 2008 19:38:00 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/2008/01/22/transparency-layer-slowdowns/</guid>
		<description><![CDATA[As the documentation mentions, a transparency layer allows subsequent drawing to be rendered in a separate, fully transparent buffer before being composited to the destination context. In the absence of a clipping region, this buffer is the same size as the destination context, requiring a context-sized buffer regardless of the actual drawing bounds. Creating a [...]]]></description>
			<content:encoded><![CDATA[<p>As the documentation mentions, a transparency layer allows subsequent drawing to be rendered in a separate, fully transparent buffer before being composited to the destination context. In the absence of a clipping region, this buffer is the same size as the destination context, requiring a context-sized buffer regardless of the actual drawing bounds. Creating a transparency layer for a small section of content, then drawing this layer in a window, for example, results in a window-sized buffer for the layer. When the layer is composited into the destination, the entire buffer must be composited &#8212; CoreGraphics doesn&#8217;t keep track of where the actual drawing is.</p>
<p>This, of course, is slow, especially for several transparency layers.</p>
<p>To help speed things up, clip the context to the bounds of any drawing in a transparency layer before beginning the transparency layer, such as below:</p>
<pre>CGRect artRect = CGRectMake(50,50,100,50);
CGContextClipToRect(context, artRect);

CGContextBeginTransparencyLayer(context, NULL);

/* Draw layer content here */

CGContextEndTransparencyLayer(context);
</pre>
<p>I&#8217;ve created a <a href="/static/transparency_layer.zip">demonstration program</a> to illustrate the effects of clipped vs. unclipped transparency layers. To see the effects, open Quartz Debug (/Developer/Applications/Graphics Tools/Quartz Debug.app) and turn on &#8220;Flash screen updates.&#8221; Then, open the Transparency Layer program. There are two windows, the left showing the drawing without clipping and the right clipping to the approximate art bounds. The views are redrawing four times per second. Notice that the unclipped view redraws its entire content while the clipped view redraws only the actual art.</p>
<p>Finally, using <code>-[NSView setNeedsDisplayInRect:]</code> clips the drawing to the specified rect.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2008/01/22/transparency-layer-slowdowns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Leopard CGWindowList* APIs</title>
		<link>http://shiftedbits.org/2007/11/08/leopard-cgwindowlist-apis/</link>
		<comments>http://shiftedbits.org/2007/11/08/leopard-cgwindowlist-apis/#comments</comments>
		<pubDate>Thu, 08 Nov 2007 05:07:39 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Leopard]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/2007/11/08/leopard-cgwindowlist-apis/</guid>
		<description><![CDATA[Leopard brings new APIs at the CoreGraphics layer to gather information about windows on the system. These functions let you find windows relative to a known window, find all windows on the system, including those offscreen, and obtain images of one or more windows as composited by the Window Server.
However, these API&#8217;s have an interesting [...]]]></description>
			<content:encoded><![CDATA[<p>Leopard brings new APIs at the CoreGraphics layer to gather information about windows on the system. These functions let you find windows relative to a known window, find all windows on the system, including those offscreen, and obtain images of one or more windows as composited by the Window Server.</p>
<p>However, these API&#8217;s have an interesting peculiarity: when the documentation says &#8220;a CFArray of CGWindowID values&#8221; they mean a CFArray of uint32s, not CFNumbers as programmers familiar with CoreFoundation might expect. This holds true for the <code>CGWindowListCreate()</code>, <code>CGWindowListCreateDescriptionFromArray()</code>, and <code>CGWindowListCreateImageFromArray</code> functions, but the two functions that return window information (<code>CGWindowListCopyWindowInfo()</code> and <code>CGWindowListCreateDescriptionFromArray()</code>) wrap all numeric values in CFNumbers.</p>
<p>To create such an array, you&#8217;ll have to create it with CFArrayCreateMutable(), such as the following:</p>
<pre>/* Make an array with no callbacks */
CFMutableArrayRef windows = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);

/* myWindow is a NSWindow */
CFArrayAppendValue(windows, (void *)[myWindow windowNumber]);
</pre>
<p>To get the <code>CGWindowID</code> of a <code>NSWindow</code>, you&#8217;ll want to use <code>-[NSWindow windowNumber]</code>. Even though the documentation specifies that this isn&#8217;t the same number as assigned by the WindowServer, it turns out that it works fine with the CGWindow* APIs.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2007/11/08/leopard-cgwindowlist-apis/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Time Machine Menu</title>
		<link>http://shiftedbits.org/2007/11/01/time-machine-menu/</link>
		<comments>http://shiftedbits.org/2007/11/01/time-machine-menu/#comments</comments>
		<pubDate>Thu, 01 Nov 2007 02:36:51 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Leopard]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/2007/11/01/time-machine-menu/</guid>
		<description><![CDATA[The Time Machine application, when in the dock, enables access to functions for showing Time Machine, backing up now, stopping an existing backup, browsing other Time Machine disks and showing Time Machine preferences. If you&#8217;re like me, you&#8217;d like access to these features without the app in the dock; unfortunately, you can&#8217;t &#8212; by default.
I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<p>The Time Machine application, when in the dock, enables access to functions for showing Time Machine, backing up now, stopping an existing backup, browsing other Time Machine disks and showing Time Machine preferences. If you&#8217;re like me, you&#8217;d like access to these features without the app in the dock; unfortunately, you can&#8217;t &#8212; by default.</p>
<p>I&#8217;ve done a bit of digging and was able to implement all but one of these features in a menu extra. Download it and the source <a href="/static/Time%20Machine%20Menu.zip">here</a>.</p>
<p>And yes, the menu icon doesn&#8217;t scale nicely :)</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2007/11/01/time-machine-menu/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Pointless Optimization</title>
		<link>http://shiftedbits.org/2007/10/22/pointless-optimization/</link>
		<comments>http://shiftedbits.org/2007/10/22/pointless-optimization/#comments</comments>
		<pubDate>Mon, 22 Oct 2007 07:03:43 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/2007/10/22/pointless-optimization/</guid>
		<description><![CDATA[The other day I needed to write a function to give me a formatted string representation of a quantity of bytes. Pretty trivial function, but nontheless, I found myself optimizing it. I ended up with the following:
static uint64_t count = 7;
static NSString *suffixes[7] =
    { @"B", @"KiB", @"MiB", @"GiB", @"TiB", @"PiB", @"EiB"};
uint64_t [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I needed to write a function to give me a formatted string representation of a quantity of bytes. Pretty trivial function, but nontheless, I found myself optimizing it. I ended up with the following:</p>
<pre>static uint64_t count = 7;
static NSString *suffixes[7] =
    { @"B", @"KiB", @"MiB", @"GiB", @"TiB", @"PiB", @"EiB"};
uint64_t i, c;
for (i = 1024, c = 0; i < (count << 60); i <<= 10, c++) {
    if (bytes < i)
        return [NSString stringWithFormat:  @"%0.2f%@",
                                            (double)bytes / (double)(i >> 10),
                                            suffixes[c]];
}
return @"Big";
</pre>
<p> Now, optimizing away divisions (except for the final conversion to string) really doesn&#8217;t save any time at all. The creation and subsequent autorelease of a NSString will take far longer than the division operations, even for large byte counts. Thus, I believe this code sample qualifies as pointless optimization, although it was entertaining to write.</p>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2007/10/22/pointless-optimization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Color Setting Performance</title>
		<link>http://shiftedbits.org/2007/10/06/color-setting-performance/</link>
		<comments>http://shiftedbits.org/2007/10/06/color-setting-performance/#comments</comments>
		<pubDate>Sat, 06 Oct 2007 08:28:18 +0000</pubDate>
		<dc:creator>Devin Lane</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://shiftedbits.org/2007/10/06/color-setting-performance/</guid>
		<description><![CDATA[ If you&#8217;re looking to eek some extra performance out of your drawing code, take a look at how you&#8217;re setting your fill and stroke colors. Setting the color using CGContextSetRGBFillColor() or creating a new CGColorRef/NSColor object each time you set the color is quite expensive to do each time you draw. Depending on how [...]]]></description>
			<content:encoded><![CDATA[<p> If you&#8217;re looking to eek some extra performance out of your drawing code, take a look at how you&#8217;re setting your fill and stroke colors. Setting the color using <code>CGContextSetRGBFillColor()</code> or creating a new CGColorRef/NSColor object each time you set the color is quite expensive to do each time you draw. Depending on how many colors you use in your drawing, consider caching the CGColorRef objects and using <code>CGContextSetFillColorWithColor()</code> or <code>-[NSColor setFill]</code> instead.</p>
<p>A CGColorRef is 48 bytes for a RGB color. A NSColor is 32 bytes for a RGB color, plus 48 bytes for a CGColorRef. If you can afford the memory hit, you’ll see quite a bit of speed improvement from caching colors.</p>
<p>Below is the output from a small test app (source available <a href="/static/code/ColorPerformance.m">here</a>) that tests various color setting methods: (Each test is 1,000,000 iterations.)</p>
<pre>
CGContextSetRGBFillColor: 4.368422 seconds
CGContextSetFillColorWithColor, static CGColorRef: 0.599552 seconds
-[NSColor setFillColor], static NSColor: 0.832328 seconds
-[NSColor setFillColor], dynamic NSColor: 5.847799 seconds
</pre>
]]></content:encoded>
			<wfw:commentRss>http://shiftedbits.org/2007/10/06/color-setting-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.298 seconds -->
