3

I had a hard time finding any examples of how to properly use Core Image with GLKView in order to smoothly render Core Image "recipes" in response to user inputs. So, after reading the Core Image Programming Guide and the GLKView class reference, I came up with an approach that works. However, I'm not sure it's valid, so I'm hoping someone can either confirm that it's OK, or point me in a better direction.

Right now, I'm using a GLKView with a GLKViewController. The GLKView delegates drawing to its parent view controller, which implements glkView:drawInRect:. The drawing method does this:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    // make glkView's background light gray instead of black
    glClearColor(backgroundRGB, backgroundRGB, backgroundRGB, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // a custom object that holds a reference to a CIContext
    ImageEditingContext* context = [ImageEditingContext getInstance];

    // apply a core image recipe
    CIImage *outputImage = [context getFilteredPreviewCIImage];

    // draw the image
    CGRect inRect = outputImage.extent;
    inRect.origin.y = (self.glkView.contentScaleFactor * self.glkView.frame.size.height - inRect.size.height) / 2.0;
    [context.coreImageContext drawImage:outputImage inRect:inRect fromRect:outputImage.extent];
}

Specifically, I'm concerned about the last line, [context.coreImageContext drawImage:outputImage inRect:inRect fromRect:outputImage.extent]. Is it valid to call that method from within glkView:drawInRect:? As I mentioned before, this approach seems to work fine, but I became suspicious of it after running the OpenGL ES Analysis Instruments template. It flagged the line with this issue:

Multi-context Renderbuffer Usage Without Flush: Renderbuffer #2 - Your application used a renderbuffer object that has been updated in a different context without a subsequent flush operation.

My GLKView and CIContext are both set up with the same EAGLContext, so I'm not quite sure what the error message is referring to. Any insight is much appreciated!

rickster
  • 124,678
  • 26
  • 272
  • 326
gilby
  • 232
  • 2
  • 13
  • 1
    As far as I can tell, your code is as good as it can get. As you've noted, you're creating the CI context from the same GL context your view is drawing with, and that warning specifically pertains to actions taken in another context. My guess would be CI is creating its own private GL context (using the same sharegroup as the context you passed in), doing all its work there, and not flushing when it's done. (Ewww.) [Filing a bug](http://bugreport.apple.com) might be a good idea. – rickster Mar 04 '14 at 00:44
  • Thanks for taking a look, @rickster! I'll go ahead and file a bug. – gilby Mar 12 '14 at 05:06
  • @gilby Did you ever figure out what was wrong. I'm getting the same issue for just about the same code. – otusweb Jun 16 '17 at 13:45
  • @otusweb I didn't, but I've switched to Metal, which is much faster! – gilby Sep 27 '19 at 16:56

1 Answers1

0

I have successfully accomplished this with a glkview. It sets up the buffers automatically with an OpenGL aware view. You do not need the buffer code at all, in fact the glkview requires about 3 lines of code if properly set up. The app is confused since it automatically sets up the buffer for you, then you create a second one and do not flush it for every frame causing many memory issues. It seems you are also creating multiple contexts, which is also a no no. Read the CIImage Programming guide. I have a UISlider that adjusts the image in real time using a glkview. All you need to do is initialize the glkview, bindDrawable, drawImage from CIContext. Make sure your CIContext is initialized with an EaglContext. You are right about one thing....the documentation is non existent. Good luck.