For example, an OS X IOSurfaceRef must be locked before accessing the data with the CPU. The calls to lock and unlock the surface are simple enough, but why repeat them? Here's a function that does that clearly:
OSStatus CallBlockWithIOSurfaceLockedForReading(IOSurfaceRef surface, OSStatus (^block)(void))
{
uint32_t seed = 0;
OSStatus error = IOSurfaceLock(surface, kIOSurfaceLockReadOnly, &seed);
if (!error)
{
error = block();
OSStatus unlockError = IOSurfaceUnlock(surface, kIOSurfaceLockReadOnly, &seed);
if (!error)
error = unlockError;
}
return error;
}
And a call to that looks like:
CallBlockWithIOSurfaceLockedForReading(surface, ^OSStatus{
void *bytes = IOSurfaceGetBaseAddress(surface);
// do something with bytes here.
// do something with bytes here.
return noErr;
});
This pattern ensures that you get consistent behavior wherever in your code you need to read data from an IOSurface, getting the appropriate error values, and always keeping the calls balanced, which is critical.
No comments:
Post a Comment