Category Archives: OS X

C++ Development OGRE OS X

By-value static member variables & XCode debug builds

Well, this had me baffled for a while. I’ve been beavering away on allowing custom, user-supplied memory allocators in Ogre, hopefully for inclusion in the upcoming 1.6, and I came across a very weird problem in OS X. The wrapper for customising regular allocations (ie new/delete as opposed to STL allocations, those are in a different std::allocator compatible class), looks like this:

template <class Alloc>
class AllocatedObject
{
protected:
    static Alloc smAllocPolicy;

Pretty obvious stuff, we clearly redirect new/delete operators via that allocator policy. We then go on to define some default allocators (which can be replaced), something like this:

typedef AllocatedObject<StdAllocPolicy> DefaultAllocatedObject;
typedef DefaultAllocatedObject SomeObjectAlloc;

.. and then in our first-party class definition:

class SomeObject : public SomeObjectAlloc
{

All fairly straight forward – all that typedefing is just a compact way of allowing per-class user configurable allocators while still keeping the type duplication to a minimum. I can also place those typedefs in such a way that they can be easily replaced just by user headers or preprocessor blocks. Now, obviously I need to instantiate that smAllocPolicy member, otherwise I’m in trouble. So, here’s what I initially tried to do, in a cpp:

template <> DefaultAllocationPolicy DefaultAllocatedObject::smAllocPolicy;

Seems ok, right? Again I’ve used the typedefs here so that the instantiation will work even if I changed the basis for the types. This worked fine on Visual C++ 2005, Ubuntu 7.1 and in release mode on OS X. But, in debug mode on OS X, I got this:

ld: Undefined symbols:
__ZN4Ogre15AllocatedObjectINS_14StdAllocPolicyEE13smAllocPolicyE
/Users/steve/projects/Shoggoth/ogre/Mac/Ogre/../build/Ogre.build/Debug/Ogre.build/Objects-normal/ppc/OgreEntity.o reference to undefined __ZN4Ogre15AllocatedObjectINS_14StdAllocPolicyEE13smAllocPolicyE
/usr/bin/libtool: internal link edit command failed

WTF? I double-checked that the .cpp was included in the target, that the .LinkFileList file included the right object file, that ZeroLink was disabled (not that that would have any effect but to delay any link errors until runtime anyway). I tried getting rid of the typedefs and making it explicit, no dice. It had me scratching my head for some time, I was convinced I was instantiating this static and the object file was getting linked, so why the problem? In the end, the solution was to to change the instantiation to this:

template <> DefaultAllocationPolicy DefaultAllocatedObject::smAllocPolicy = DefaultAllocationPolicy();

I’m really not sure why in debug mode I was forced to include an explicit construction & assignment of this policy class rather than it being constructed by value in place, as seems to have happened with the other compilers and indeed in release mode under OS X. I usually don’t hold complex types statically by value, so usually I’d have an explicit initialisation in code like this to init pointers to 0 or numerics to something reasonable, so I wouldn’t have tried this particular thing on OS X before, but I did not expect to have to construct a complex type manually (and copy-construct effectively, although that’s likely to be optimised out). The fact that it worked in release mode and on other compilers makes me wonder how idiosyncratic that behaviour is. Maybe I’m just too tired and need to read Stroustrup again. If anyone has a rational explanation, I’d be glad to hear it.

OGRE OS X

Working around GLSL attribute aliasing problems on OS X

As much as I love using OS X, one of the double-edged swords is that the graphics driver updates are controlled by Apple. On the one hand, that’s a bonus because you have a better idea of what you’re dealing with out in the wild, and people get prompted to update their drivers (as part of the regular OS X auto-update). On the other hand, it’s a pain in the ass because the drivers tend to lag behind those from the GPU manufacturers and therefore have bugs the mainstream ones don’t.

I just recently committed a patch from ‘hellcatv’, one of the more prolific Mac users in our community to deal with a few driver bugs in some of the older Powerbooks, and also some quirks of the recent Intel GMA-based iMacs – stuff like choking on glCompressedTexSubImage2DARB for no good reason (ie, forget uploading part of a DXT-compressed texture, it’s all or nothing). I’m indebted to him for testing on a huge range of Macs that I’d never have access to, without spending a load of cash and filling up my home office with yet more surplus hardware (my wife would not entirely approve of either methinks). One of the remaining problems we’ve had is that the OS X GLSL drivers on the recent NVIDIA-based MacBook Pros suffered from vertex attribute aliasing-associated performance problems that other platforms did not.

Now, NVIDIA has always had a fixed set of vertex attribute assignments for the built-ins – gl_Vertex is 0, gl_Normal is 2, etc. If you used gl_Normal in a shader, but also bound a custom attribute (say, skeletal blend weights) to index 2 too, you’d get a performance drop because of the aliasing. That’s fine – so instead, when we used custom attributes, we didn’t fix the indexes we used, we let the linker decide, taking into account what was actually used in the shader. We’d include the attributes in the shader, and then after glLinkProgramARB, we’d ask the program object what indexes it had chosen for the custom attributes, then wire them up that way. The well-behaved drivers (Windows, Linux) on NVIDIA would avoid clashing with any built-in attributes that had been referenced in the shader and we’d have a nice tight list of unique indexes, but on OS X, the driver would stupidly often assign custom attributes to built-in indexes that were in fact being used in the shader. Tsk, bad driver, no treats for you today.

It’s been reported to Apple as a bug, but so far, no dice on the fix front, so I decided it was time to try to work around it. The first thing I tried was simply telling the driver at the pre-link stage that I wanted any occurrences of the custom vertex attributes we supported to be placed out of the way of any possible built-ins that might be used. So for example, I did this:

glBindAttribLocationARB(mGLHandle, 6, "blendWeights");
glBindAttribLocationARB(mGLHandle, 7, "blendIndices");

That seemed to take effect, and calling glGetAttribLocationARB after the link reflected that I was indeed getting indexes 6/7 bound, rather than the 1/2 that the driver kept picking before (bad, because I used gl_Normal in this shader which is index 2). However, despite the indexes being out of the way of anything else, the shader still performed really poorly. I tried a few other indexes, like 14 and 15 which overlap with the top 2 UVs but which are rarely used (you can’t exceed 15, at least on NVIDIA), but the result was the same.

Cue head-scratching. There should be no aliasing problems anymore, yet still the shader performs like an asthmatic ant carrying some heavy shopping. So, the last thing I tried was going the whole hog, and implementing support for custom attribute replacements for all of the built-ins, all at known, fixed indexes matching currently known hardware defaults & limitations, ie:

Index Built-in Custom Name
0  gl_Vertex vertex
1 n/a blendWeights
2 gl_Normal normal
3 gl_Color colour
4 gl_SecondaryColor secondary_colour
5 gl_FogCoord n/a
7 n/a blendIndices
8 gl_MultiTexCoord0 uv0
9 gl_MultiTexCoord1 uv1
10 gl_MultiTexCoord2 uv2
11 gl_MultiTexCoord3 uv3
12 gl_MultiTexCoord4 uv4
13 gl_MultiTexCoord5 uv5
14 gl_MultiTexCoord6 uv6, tangent
15 gl_MultiTexCoord7 uv7, binormal

And what do you know, that works. The skinning shader runs considerably better like that – still not great, I think the Apple GLSL implementation is not that good, but at least 2-3 times faster than it did before. It kinda sucks to have had to do it that way, I really liked being able to leave it up to the driver to organise the attribute bindings and only using the ones I needed because that’s more in the spirit of the GLSL way, but clearly being more rigid is the more reliable way. I know that I could have packed the tangent in attribute 6 instead to save a UV entry, but the use of 6 seemed to have some performance issues still so I’ve gone with the fixed bindings I would have used with ARB programs. It’s incredibly rare to need more than 5 UVs going into a vertex program anyway in my experience.

So, the advice appears to be that if you need a custom binding in GLSL and you want it to run well on a Mac, using all custom attribute bindings in the vertex shader and fixing the indexes seems to be the way to go.

OS X Tech

Nasty Surprises

I don’t have as much time with it as I’d like, but over the last six months or so I’ve grown to like OS X. It’s slick, easy to use and generally just gets out of my way, and I keep finding neat little tricks I don’t expect (like dragging the icon on the title bar of the current window to create a shortcut to the document you’re viewing – nice).

However, today something about it had me swearing like a trooper. I’m actually surprised I haven’t come across it before, but the crux of the matter was the behaviour of Finder when you copy a folder into a location which already contains a folder of the same name. In Windows  Explorer if you answer ‘Yes’ to the confirmation dialog the contents of the folder you’re copying will be merged into the destination, only overwriting files of the same name. Finder conversely will completely replace the copy of the folder that is currently there, deleting its previous contents and replacing them with only the contents of the source folder you’re copying. I managed to completely screw my Eclipse install this way (which I use for Java dev sometimes) by copying ‘features’ and ‘plugins’ folders from a plugin archive, which ended up excising every previous plugin and feature that was already in there, including the core. Gah.

In fairness, the prompt that comes up does ask you whether you want to replace the folder that’s there. However, having been conditioned on Windows, I interpreted that in the non-literal sense to mean ‘merge’ and answered in the affirmative, little knowing that it really did mean ‘replace’. Unfortunately the replaced content doesn’t end up in the Trash either, so I had to reconstruct my Eclipse install from scratch. Once again, gah. Luckily it didn’t take that long since it kept all my automatic remote plugin sources, it’s only manually installed plugins like this one that needed re-doing.

I guess it’s arguable that the reason for my confusion was that I’m just used to Explorer’s interpretation of ‘replace’ to mean ‘replace files in folders’ and not ‘replace entire folders’. I’m therefore not going to suggest that this paradigm is necessarily wrong and should be changed to match Windows – in fact I’ll acknowledge that semantically it’s an accurate description of the operation. However I do think that not providing a merge option is a serious oversight in Finder, since it’s very common to want to do this. Simply including a third option called ‘Merge’ in the confirmation dialog which currently just says ‘Replace’ or ‘Stop’, would serve a dual purpose – indicating to users familiar with other OS’s what the true meaning of ‘Replace’ is in this context, and also allowing you to perform an operation that is after all very useful. OS X prides itself on how obvious and direct most operations are and on the whole it succeeds, but in this case, the ease with which a simple misunderstanding can cause permanent data loss is unacceptable to me. Come on Apple, you can do better than that.

OS X

MacHeist 2008

Damien kindly sent me a link today to MacHeist, a site that sells bundles of Mac software for a limited time at rather extraordinary prices, while also donating 25% of the revenue to charity. I took a look, and on seeing the bundle that was there, immediately bought it. It’s $49 for 14 applications, and whilst inevitably there’s some dead wood in there and things I wouldn’t normally buy, the inclusion of PixelMator made it a no-brainer for me on its own – the entire bundle is $10 cheaper than buying PixelMator is usually anyway. Total bargain – I’d intended to buy PixelMator anyway but hadn’t gotten around to it yet, so now I get it cheaper and with a bunch of other stuff thrown in.

I can also see myself using SpeedDownload since I’m currently managing with the free version of iGetter (unfortunately there’s no direct equivalent of Free Download Manager on OS X). Some of the others look interesting too although I probably would never have bought them on their own.

So, a good deal, and the charity aspect is good too. If you want to take advantage of this offer you only have about a day and a half to do it. :)

Linux OS X Tech Windows

What do you know, other OS’s have teething problems too

Those of you who read this blog regularly will know that I’m pretty unimpressed with Vista, whether it’s the ham-fisted UAC implementation, the ‘burn resources for zero practical benefit’ attitude of Aero and the generally derivative nature of most of its enhancements. As an OS it rates very much in the ‘could do better’ camp, and when measured against a 5-year development cycle it edges into ‘what the bloody hell have you all been doing?’ territory.

However in the interests of balance it’s worth pointing out that it’s not the only OS released recently to have some issues. OS X 10.5 aka ‘Leopard’ has just been released, to less than a rapturous welcome in some cases – it appears there’s much to like about it, but there’s also some counter points and even a fair amount of bitching going on about some of the design elements, and it appears that the upgrade can be far from smooth for users of some add-on software. The latter you could blame on said add-on software screwing with the kernel, but it appears to be fairly popular software so I’m surprised Apple didn’t incorporate that into their testing, given how big they are on usability. I never jump in on a first iteration of core software like this anyway, I don’t have the time for it, although my Mac is currently in for repairs in any case.

There was also the new release of Ubuntu, 7.10 aka Gutsy Gibbon, and that’s been fraught with some networking issues in particular – the kind of thing you would have thought should be pretty solid by now, and some people are also having some Xorg issues (something I’m not unused to!) with the new version.

Of course, no doubt all these things will be rectified via patches and the like, but it’s only fair to say that Microsoft aren’t the only ones to have rollout problems on a new OS. I have to say that my installation & setup experience with Vista was actually very good (especially since drivers had stabilised by the time I installed it), it’s the end result that I found rather underwhelming.

I do intend to install Leopard early next year, and the new Ubuntu may well get an outing on one of my new test boxes I plan to set up soon. In both cases I’ll let others take the initial hit though, early adoption is not something I particularly have time to waste on right now.

OS X Personal Tech

Schrödinger’s Mac

My MacBook Pro appears to now be in a state of quantum flux. As previously mentioned it worked fine yesterady when I took it in, and indeed I used it for most of the morning (testing) and most of the evening (doing some Dx10 work). This morning though, it was back to the same problem so I took it in again to demonstrate it.

As if to mock me, whilst it at least demonstrated the problem on boot up, as I was filling the incident report form in and it was sitting idly on the desk untouched next to me, it suddenly decided to right itself. ‘Hey, I can work when I want to!’ it jeered. Since the engineer isn’t in on Saturdays I booked it in for surgery on Tuesday next week and took it home on the assumption I might get some use out of it, to which the MBPs response was to fail again when I got home. Spiteful little bastard.

Clearly there’s some kind of bad connection or temporary problem, I’ve tried the obvious highly technical things like wiggling the lid hinge and light ‘tapping’ to see if it’s a physically dodgy connection but it has no effect. Maybe it’s temperature related, although when I had it back home I left it on for a while to get a little warm and it didn’t change. Hey ho.

I’m reminded of a certain classic british sitcom:

Percy: He must be on his last legs by now, My Lord.
Edmund: Yes, but how many sets of legs has that man got? Really, I wish he’d make up his mind — either he dies, or he lives forever! It’s his shilly-shallying that’s so undignified.

Amen.

OS X Personal Tech

MacBook Pro Lives!

Typical. Not unwelcome, but still typical. After experimenting multiple times with my broken MacBook Pro last night, I’d given up and first thing this morning I took it to my local Apple reseller, iQ (actually there are 2 in the island, but iQ are ‘Premier’ resellers and that’s where I bought it). I was explaining the problem and fired the machine up, and what do you know, it was fine. :?

Weirdly, the last thing I’d tried last night was clearing the PRAM & NVRAM (hold Command-Option-P-R when starting) since I’d read some reports of that solving some unusual issues. Having done that, nothing changed, but I assumed it had actually cleared the settings because I got the ‘chime’ at powerup time, which I don’t normally because I turn the speakers off, one of the settings kept in the PRAM I think. So I’d been resigned to it being a genuine hardware fault.

So I had a chat with manager Justin whilst I was there, and based on the description it sounds like either it was a temporary glitch which resetting did solve after one additional power cycle, or it’s an intermittent hardware problem, perhaps with the GPU or the DAC which feeds the LCD (he seemed to think that was more likely given the symtoms than a broken LCD, even though the external monitor worked). Since getting back I’ve run the Apple Hardware Test in ‘extensive’ mode but it didn’t highlight anything. We’ll have to see.

He also told me that iQ fix Apple hardware in-house, Justin has all the Apple Technician certifications so he can just take it into ‘the basement’ to replace bits with full warranty cover. That’s really handy to know and makes me feel happy about having bought it there. On the whole they were really helpful and friendly so I can say I had a positive customer experience there. It’s only a small place and they don’t have that many staff (it only opened about a year ago) but I hope they carry on.

He also told me they don’t think they’ll get Leopard today despite being all geared up for it with extended opening times and such – the Jersey store even put on drinks and nibbles that they’re either not going to use or will just grow fat on in-store :)

OGRE OS X Personal Tech

MacBook Pro Dies

Yes, I fired up my MacBook Pro today with the intention of getting on with some more Dx10 work, but was greeted with a completely corrupted display. It appears that other things are still working, as I can still make some things out through the garbage – right from power on I get the top third of the screen as mostly greyish blank, and the bottom two-thirds as a ‘smeared’ version of what I should be seeing, although when I tried sleeping and waking it, I temporarily got a correct login screen view in the top third but it slowly faded into garbage, whilst the bottom section was still smeared. Grr.

So, it’s completely unusable. Only just over 3 months old too, and it worked fine on Monday with no ‘events’ in between that would suggest breakage, it just died on its own. Looks like I’ll have to take it down to our local Apple reseller – I only hope they can just replace the LCD or something, since I spent ages setting up both OS X and Vista the way I like, and I really don’t want to do that all over again. I also had some work in progress code on there I’d prefer not to lose, although it wouldn’t be a disaster if I had to.

In all, grr.

OS X Tech Windows

Incoming Leopards

So, a formal release date for Mac OS X 10.5 aka ‘Leopard’ has been set now, 26th October or just over a week away. Really it should have been out by now, this represents a 4-month delay on the original release schedule which was to see it released with the ‘Santa Rosa’ Macbook Pro line – slightly disappointing but keeping it in context, it could have been a lot worse.

The pricing is kind of interesting – for a single license it’s £85, which places it smack in the middle of the Vista price range (OEM versions of Vista range from £60 to £100, ignoring the pointless Home Basic), but far more interesting is the ‘family pack’, which can be installed on up to 5 machines in a single household for £129. Now, I’m doubting that very many households actually have 5 Macs, but even if you have 2 it’s a saving, and it starts looking very attractive indeed at 3. I’m actually surprised Microsoft hasn’t done something like this to encourage the flagging sales of Vista, although I’m guessing the demand would still be stunted somewhat by the upgrade requirements in a family environment where apart from little Johnny who perpetually salivates (or worse) over Crysis screenshots, the rest of the household are likely to be running sub-par machines.

Also, I’m sure I’m not the only one to notice that ‘upgrade’ versions of operating systems seem to have quietly become irrelevant. OEM versions of Vista are cheaper than buying a retail upgrade from XP, and Apple don’t even seem to offer upgrade deals for Leopard; the price probably doesn’t warrant it. Hopefully this is an increasing sign of commoditisation in the operating system market, which can only be a good thing. The days when you could sell an operating system based on whether it did ‘true’ multitasking or whether it crashed less or not are finally over – consumers rightly just expect these things as standard. The differentiating factors in commercial operating systems now are not so much major core features (although they can still be a factor, like Time Machine), but style and ease of use. Application compatibility is still a factor to some degree, especially given the considerable success Microsoft has had over the years wooing developers to be single-platform with easy to use tools & frameworks (starting as far back as the first version of VB), but in the wider industry more and more application stacks are now cross-platform, thanks in no small part to the open source community; so you’re rarely stuck without a good application option on any platform now. So without style/flair or ease of use, you have no real need to buy a commercial operating system anymore, there are plenty of free ones that will give you the same thing with perhaps a little more coaxing (e.g. the next version of Ubuntu, which has Compiz enabled by default).

This is where Vista failed in my view. Style wise it’s stuck in a difficult situation – you can’t change too much without alienating the existing user base, but at the same time when you don’t have that many core new features that people need (hence the artificial welding of large chunks of the Dx10 featureset to Vista when most of the major features could have been delivered in XP, a transparent shoring up of the value proposition) , you have to try to do something interesting. The interface changes in Vista feel mostly derivative and ‘bolted on’ in a way that makes them entirely discardable – necessary perhaps to scale back to people who can’t run Aero, but it also saps the value right out of them. I can happily run Aero on my machine, I just choose not to because I don’t see the point, my user experience is not enhanced in any substantive way by having it turned on, as opposed to my battery life and ‘lap temperature’ which certainly benefit from having Aero off. Because OS X was built with the assumption that hardware graphics were available everywhere, the effects that are there feel like they have more of a core purpose. They also don’t toast the machine constantly ;) . I have no idea how much actual usability benefit Compiz brings to Linux in everyday use since I’ve never tried it, perhaps others can comment on how well that works.

Still, I’m not going to be rushing out and grabbing Leopard because although there are a few things I like the look of (particularly XCode 3), I’m not champing at the bit, and I have plenty to keep me busy for a couple of months anyway. I’ll let it bed in a bit first and perhaps upgrade early next year.

OGRE OS X Tech

Branches and precompiled headers in XCode

Here’s a quick tip for you – XCode helpfully makes using precompiled headers in your project a cinch, even easier than trusty old MSVC in fact, which is a good thing. Unfortunately, it also places the result of said precompilation step in a shared location by default, namely /Library/Caches/com.apple.Xcode.$(UID)/SharedPrecompiledHeaders. It actually creates folders in this location corresponding to each combination of target name and a hash of the compiler settings used. The idea here, which seems sound to begin with, is that it wants to try to re-use the results of the precompilation as many times as possible.

Again, this unfortunately becomes a problem the minute you want to use multiple branches of the same project / target, because the target names and compiler hashes are identical, but the headers themselves can be very different – and you start getting funny compiler errors when everything in the code looks perfectly fine. The problems of course go away the minute you hit ‘Clean’ or touch a header that’s included in the PCH, and I’d missed this problem until now because I just happened to be jumping between branches relatively infrequently on OS X so one of those conditions masked the problem. Then all of a sudden it bites me in the ass when I’ve seemingly made no changes.

It’s easy to fix, just hit Apple-I on the top-level project node, pick ‘All Configurations’ and ‘Build Locations’ and change the ‘Precompiled Headers Cache Path’ to something relative to the project. Presto, no more branch-hopping PCH issues. Once again the default XCode setup really doesn’t like to play with multi-branch development practices, something that can confuse otherwise experienced developers who are new to the tool. Well, it confused me briefly anyway :?