I have written two custom Core Image metal kernels which I'm using to produce a CIImage (by chaining several filters). I'm drawing the output image in a simple view and whatever I use (CIImage, NSImage, CGImageRef), the image appears corrupted on screen, like some sort of graphics corruption (I've tried on two different machines with different systems). However if I add a simple step to write the image to disk from the CIImage then read it from disk and draw it in that very same view, then all is fine and the image appears correctly. What could possibly be happening here?
Core Image drawing corruption
I've done some further experiments: if I set the CGImage (obtained from the CIImage) directly onto the contents
property of the layer
of my view, then it works and display fine. But if I implement drawRect()
and draw the CGImage into the CGContext using CGContextDrawImage()
then it appears corrupted. How weird is that?
For anyone at Apple seeing this, I filed FB12608056 with sample code and screen recording.
Can you please upload some screenshots to show what "corrupted" means? Thanks!
@FrankSchlegel here's a screen recording, top view is drawing the image in drawRect()
, bottom view is assigning the image to the layer contents. The bottom view display what I expect. http://tclementdev.com/coreimage_metal_test.mov
Hmm, this is really hard to debug without seeing the actual filters. But if I would need to guess, I'd say the implementation of the ROI callback (passed when calling the CIKernel
) is wrong. I can also recommend using a MTKView
for displaying a CIImage
instead of using Core Graphics. There is a sample from Apple showing how to do that.
@FrankSchlegel wow thank you, I added the ROI callback (simply returning the images full extent) and the top image doesn't look corrupted anymore. I'm so confused as to why the default behavior is any different when an ROI callback is not specified, wow. Still not the end of the story though, when drawing large with interpolation disabled (NSImageInterpolationNone and kCAFilterNearest), the top image is doing something odd, new video here -> http://tclementdev.com/coreimage_metal_test2.mov
The image view width is a multiply of 6 and should be able to represent all pixels as they are without any trick, so it doesn't seem like it should do that.