BradLarson/GPUImage — pull request #631 by karlvr (2012-11-10 22:51:38+00:00)
Title: textureNoLongerNeededForTarget would release texture before all...

... the initial filters in a filter group had used it

This problem manifests when shooting photos (ie. the conserve memory is active) and operating a chain of filters (eg. camera -> sketch -> tilt shift) where there is a filter group with multiple input filters after another filter (as above). One of the filter group's initial filters would get an empty input texture as the texture would be released early.

This is because the outputTextureRetainCount is based on number of targets. But a filter group target actually represents initialFilters filters (ie. possibly more than 1).

This change proxies delegate callbacks to textureNoLongerNeededForTarget from initialFilters in a filter group, through the filter group so it can run its own "retain count", before telling the actual delegate to release the texture.

I have tested this with a simple example of Camera -> Sketch -> TiltShift (which is a filter group). The problem appeared when you shoot a photo - the tilt shift would have the blurry bit intact but the in-focus part of the image would be black (as the texture was released).

This problem is now corrected and the same number of textures are released (so they are still being released, just later).

PS. I did try solving this by having GPUImageInput report how many retains it would use, and then changing the calculation of outputTextureRetainCount to call that method for each target and sum, rather than just using targets.count. That required changes in lots of places and I'm pretty sure that the attached solution is nicer.