The Shape of Everything
A website mostly about Mac stuff, written by Gus Mueller
» Acorn
» Twitter
» Maybe Pizza?
» Code
» Archive
December 18, 2017

Part I, Part II, Part III.

A status update of sorts.

I got the redraw issues with MTKView figured out. The problem was that I would ask the Metal view to update 400 times over 5 seconds, and it wouldn't. Presumably this was because of a high load on the system while doing a flood fill or magic wand operation, because once I stopped or slowed down a bit everthing caught up and started drawing again. I think MTKView treats setNeedsDisplayInRect: as more of an advisement, and if you really want things to draw then you also need to call draw on the instance. Because of the way things are setup in Acorn I could make this happen with every canvas update call, but for now I'm only doing so with high load operations like flood fill and brushing.

Deep color is also working through Metal now, and everything is great with 128 and 32 bit images. 64 bit images though… well, there's a mismatch between what the pixel format Acorn currently uses for this format and what IOSurface will take.

Acorn 6 and earlier uses uint16_t to store a pixel component (16 bits per component x 4 for RGBA = 64 bits) because that's super easy to grab the values out of for picking out colors or finding opaque bounds of images.

CGBitmapContext supports 16 bit RGBA (kCGImageAlphaPremultipliedLast), and Core Image does as wel (kCIFormatRGBA16), but IOSurface doesn't.

IOSurface does however support 16 bit ARGB, which would be easy enough to switch to, but CGBitmapContext and Core Image don't.

The only format that all three support are 16 bit half float RGBA.

Half what? What's a half float? Well, it's a format that GPUs are very keen on but there's no built in type for it in C, Objective-C, or Swift. This makes reading the individual pixel values kind of a pain.

There's some fancy bit twiddling magic out there for treating a half float as a uint16 and then converting that into a regular 32 bit float, but you can also use vImage's vImageConvert_Planar16FtoPlanarF to do the same with some a little bit of setup. That's what I'll probably end up doing. (Intel also has some Intrinsics for doing these, but they crash the clang compiler when I try).

I'm not keen on changing a pixel format in a .1 update of Acorn, but with enough testing it should be alright. I just have to carefully create some new OpenCL routines and then all will be good. Right?