Silence-GitHub / BBMetalImage

A high performance Swift library for GPU-accelerated image/video processing based on Metal.
MIT License
988 stars 126 forks source link

Create new ImageSouce and delete old ImageSource. #61

Closed lygialiem closed 4 years ago

lygialiem commented 4 years ago

Hi Silence-GitHub! It's me again. I have an issue about imageSource = BBMetalStaticImageSource(image: UIImage) which chains about 14 BBMetalBaseFilter. Then I have a button, when click on that, I want to create a new imageSource and add one more BBMetalBaseFilter so that the chains now have 15 tool. But when I touched the button, App did not reply anything (It did not crash, memory measure still fine, also CPU processing). Here is my code:

  1. initialize a imageSource at the app begin:
    guard imageSource == nil else { return }
        imageSource = BBMetalStaticImageSource(image: image)
        var bbMetalImgSource = imageSource?.add(consumer: allTools.first!)
        let lastTool = allTools.last!
        allTools.enumerated().forEach { [weak self] (index, editTool) in
            guard let wSelf = self ,
                index != 0 && index < wSelf.allTools.count - 1
                else { return }
            bbMetalImgSource = bbMetalImgSource?.add(consumer: editTool)
        }
        bbMetalImgSource?
            .add(consumer: lastTool)
            .addCompletedHandler { [weak self] (_) in
                if let wSelf = self, let editedImg = lastTool.outputTexture?.bb_image {
                // Do some Stuff with new Image.  
                }
        }
        imageSource?.transmitTexture()
  2. Remove ImageSouce and add one more filter when click button:
imageSource?.reset()
imageSource?.removeAllConsumers()
imageSource = nil

let currentFilterTool = filterToolCats[indexPath.section].filters[indexPath.row].config.filter
        allTools.insert(currentFilterTool, at: 0)
  1. Create a new imageSource:

Same as step 1.

lygialiem commented 4 years ago

Is there anyway to insert one or two New Filter to the chain with the same ImageSource?

Silence-GitHub commented 4 years ago

This library only provides add(consumer:) to set up filter chain now. Maintaining filter chain is our work.

There may be problems in your code.

  1. Each filter in allTools calls add(consumer:) more than once. If a filter needs only one consumer, we should not call add(consumer:) more than once without removing old consumers.

  2. The reset() function of BBMetalImageSource is private. How can you call it like imageSource?.reset()? If we don't need the image source anymore, we don't need to call reset(). Removing consumers is enough. If we need to keep it and set up a new filter chain, remove old consumers and add new ones. If we need to change the image, call update(_:) function.

lygialiem commented 4 years ago

Hi! Thank you for your suporting.

  1. My code above is to Add many Filters as a chain. Because there are 14 tools in allTools, so I make a loop in allTools to make a chain with imageSource. I created bbMetalImgSource to chain every tool in allTools.
  2. revmove old consumers, you are meaning that we make it nil, right?
Silence-GitHub commented 4 years ago

If we call a filter function add(consumer:) twice, the filter has 2 consumers. If the filter needs only one consumer, we should call removeAllConsumers() before each calling add(consumer:).