GPUImage2 icon indicating copy to clipboard operation
GPUImage2 copied to clipboard

UIView.layer must be used from main thread only

Open chengkaizone opened this issue 6 years ago • 8 comments

I am having a headline warning when I record my video using GPUImage2

chengkaizone avatar Jan 10 '18 14:01 chengkaizone

Code: sharedImageProcessingContext.context.renderbufferStorage(Int(GL_RENDERBUFFER), from:self.layer as! CAEAGLLayer)

chengkaizone avatar Jan 10 '18 14:01 chengkaizone

I have/had the same issue.

as a monkeypatch I changed the following lines (starts at line 62) in the RenderView.swift file:

sharedImageProcessingContext.context.renderbufferStorage(Int(GL_RENDERBUFFER), from:self.layer as! CAEAGLLayer)

var backingWidth:GLint = 0
var backingHeight:GLint = 0
glGetRenderbufferParameteriv(GLenum(GL_RENDERBUFFER), GLenum(GL_RENDERBUFFER_WIDTH), &backingWidth)
glGetRenderbufferParameteriv(GLenum(GL_RENDERBUFFER), GLenum(GL_RENDERBUFFER_HEIGHT), &backingHeight)

by this:

let group = DispatchGroup()
group.enter()

DispatchQueue.main.async {
    sharedImageProcessingContext.context.renderbufferStorage(Int(GL_RENDERBUFFER), from:self.layer as! CAEAGLLayer)
    group.leave()
}
group.wait()


var backingWidth:GLint = 0
var backingHeight:GLint = 0
glGetRenderbufferParameteriv(GLenum(GL_RENDERBUFFER), GLenum(GL_RENDERBUFFER_WIDTH), &backingWidth)
glGetRenderbufferParameteriv(GLenum(GL_RENDERBUFFER), GLenum(GL_RENDERBUFFER_HEIGHT), &backingHeight)

I know this will block the thread but since it's a very negligible time for my use case I consider it enough.

The reason is that

sharedImageProcessingContext.context.renderbufferStorage(Int(GL_RENDERBUFFER), from:self.layer as! CAEAGLLayer)

is the reason the warning is raised, but if you only put that line on the main thread then backingWidth and backingHeight are still equal to zero, because the renderbufferStorage hasn't had time to finish on the main thread. so making the rendering thread wait for the renderbufferStorage seems the simplest solution for me.

jwoodrow avatar Feb 08 '18 14:02 jwoodrow

Thanks @jwoodrow! Your fix removed a crash that I was having in iPhoneX (crash that was only in happening in iPhoneX)

jvk75 avatar Feb 16 '18 08:02 jvk75

@jvk75 glad I could help, although as I said this is a quick and dirty fix.

I don't have any deep knowledge of how this library works (I'd love to try and make an equivalent of this using Metal too instead of openGL because it would probably gain in performance and stability even though it would limit device compatibility) so I don't know if this will affect performance or stability for apps since technically it does pause the gpuimage thread concerned (no idea if there are multiple threads but seeing how it performs I'd wager there are).

anyway I'd use any fix/patch not confirmed by @BradLarson with caution just in case it could break something else and then you'd end up with even more issues and less possibility of assistance (it would be complicated to help on an issue in your project in 2-3 months if your code ends up being different from everyone else's if ever this became a source of a problem).

jwoodrow avatar Feb 16 '18 08:02 jwoodrow

In my use case the performance is not an issue as I only do still images. Trying anyway to move out of the GPUImage as there has not been much/any activity lately so future scares me.

jvk75 avatar Feb 16 '18 08:02 jvk75

From what I gathered, Brad has other project he's focused on and when it comes to gpuimage2 his priority was to fix the linux compatibility. I'm using this library over the objective-C one because I didn't want to have to deal with bridging headers and all, but I don't feel like gpuimage2 is not production ready since it isn't updated a lot not even issue wise.

I have the same concerns as you when it comes to lack of activity which is why I'd love to work on a Metal library similar to this but there are so many things to do in order to recreate a Metal gpuimage especially with all the image operations already available on it (plus dealing with Metal textures isn't exactly a piece of cake either)

jwoodrow avatar Feb 16 '18 08:02 jwoodrow

I change it to pull mode and it works fine:

  1. filter chain push render result to GPUImageView, and GPUImageView save it.
  2. in view's draw method: call renderbufferStorage, then render the result to canvas.

AndrewChan2022 avatar Mar 06 '20 10:03 AndrewChan2022

In RenderView-UIKit.swift file, line 62

runOnMainQueue {
            sharedImageProcessingContext.context.renderbufferStorage(Int(GL_RENDERBUFFER), from:self.layer as! CAEAGLLayer)
}

liuqiaohong0515 avatar Sep 08 '21 07:09 liuqiaohong0515