iOS Development

ios – Operating into vImage_Buffer associated peak reminiscence points. When does vImage_Buffer.free() truly free reminiscence?

Spread the love


I’m engaged on a challenge the place the UI has to generate previews for a lot of bigger nonetheless photos. I’m utilizing a C++ library to use numerous lookup tables and conversions to the pictures which requires the picture to be in a RGB float buffer. I take advantage of Speed up to transform the supply picture into Float and again right into a RGB picture. I’m managing conversion jobs via a serial DispatchQueue in order that one conversion is completed after one other.

What I’m working into is peak reminiscence points. Although I handle jobs sequentially and processing photos one after the other I pile up reminiscence within the GB vary. If I’ve sufficient reminiscence to finish all processing the reminiscence will get freed and nothing leaks – however throughout processing I’m utilizing up a number of instances extra reminiscence than I ought to.

In devices I’ve checked that I stack up vImage_Buffer situations (each operation creates 3 however I see many) every a number of MB in measurement – regardless of calling free() on the buffers within the operate on the finish.

I’m relatively clueless atm about why it piles up reminiscence? My working principle is that vImage_Buffer.free() doesn’t free reminiscence immidiately? However wants one thing to occur to really free the reminiscence (it looks like it frees it when all of the processing is completed, however these are impartial jobs actually and there’s no frequent factor that claims I am executed.). I’m truly fairly puzzled. How can I restrict the quantity of reminiscence I eat? I’ve considered retaining the buffers round – however the issue is that the pictures would not have the identical measurement.

It’s the first time I take advantage of Speed up and vImage – what did I miss?

Any perception can be a lot appreciated….

Right here is the operate (sure I do name free()):

@accessible(iOS 16.0,*)
static func processImage(from cgImage:CGImage, lookData:Information) throws -> CGImage {
    
    let width = UInt32(cgImage.width)
    let peak = UInt32(cgImage.peak)
    
    let Rec709 = CGColorSpace(identify: CGColorSpace.itur_709)!
            
    let bitmapInfo_3ChanFloat:CGBitmapInfo = CGBitmapInfo(
        rawValue:CGBitmapInfo.floatComponents.rawValue | CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.none.rawValue
    )
    
    var src_format = vImage_CGImageFormat(
        bitsPerComponent: cgImage.bitsPerComponent,
        bitsPerPixel: cgImage.bitsPerPixel,
        colorSpace: cgImage.colorSpace!,
        bitmapInfo: cgImage.bitmapInfo)!
    
    var convertible_format = vImage_CGImageFormat(
        bitsPerComponent: 32,
        bitsPerPixel: 3 * 32,
        colorSpace: cgImage.colorSpace!,
        bitmapInfo: bitmapInfo_3ChanFloat)!
    
    var converted_format = vImage_CGImageFormat(
        bitsPerComponent: 32,
        bitsPerPixel: 3 * 32,
        colorSpace: Rec709,
        bitmapInfo: bitmapInfo_3ChanFloat)!
    
    var end_format = vImage_CGImageFormat(
        bitsPerComponent: 8,
        bitsPerPixel: 4 * 8,
        colorSpace: Rec709,
        bitmapInfo: .init(rawValue: CGImageAlphaInfo.noneSkipLast.rawValue))!
    
    let to_converter = vImageConverter_CreateWithCGImageFormat(
        &src_format,
        &convertible_format,
        nil,
        vImage_Flags(kvImagePrintDiagnosticsToConsole),
        nil).takeRetainedValue()
    
    let back_converter = vImageConverter_CreateWithCGImageFormat(
        &converted_format,
        &end_format,
        nil,
        vImage_Flags(kvImagePrintDiagnosticsToConsole),
        nil).takeRetainedValue()
    
    var src_buffer = strive vImage_Buffer(cgImage: cgImage)
    
    var conversion_buffer = vImage_Buffer()
    vImageBuffer_Init(
      &conversion_buffer,
      UInt(peak),
      UInt(width),
      convertible_format.bitsPerPixel,
      vImage_Flags(kvImagePrintDiagnosticsToConsole)
    )
    
    var end_buffer = vImage_Buffer()
    vImageBuffer_Init(
      &end_buffer,
      UInt(peak),
      UInt(width),
      end_format.bitsPerPixel,
      vImage_Flags(kvImagePrintDiagnosticsToConsole)
    )
    
    vImageConvert_AnyToAny(
      to_converter,
      &src_buffer,
      &conversion_buffer,
      nil,
      vImage_Flags(kvImagePrintDiagnosticsToConsole)
    )

    let imageBuffer = conversion_buffer.knowledge.assumingMemoryBound(to: Float.self)
    let measurement = Int(width * peak * 4 * 3)
    
    strive lookData.withUnsafeBytes { (rawLookBuffer:UnsafeRawBufferPointer) in
        let lookBuffer:UnsafePointer<UInt8> = rawLookBuffer.baseAddress!.assumingMemoryBound(to: UInt8.self)
        
        let consequence = applyLook_CPP(imageBuffer, measurement, width, peak, lookBuffer, rawLookBuffer.depend)
        if consequence < 0 {
            throw Errors.ImageSDKFailed(error: consequence)
        }
    }
    
    vImageConvert_AnyToAny(
      back_converter,
      &conversion_buffer,
      &end_buffer,
      nil,
      vImage_Flags(kvImagePrintDiagnosticsToConsole)
    )
    
    let consequence = strive end_buffer.createCGImage(format: end_format)
    
    src_buffer.free()
    conversion_buffer.free()
    end_buffer.free()
    
    return consequence
}

5 thoughts on “ios – Operating into vImage_Buffer associated peak reminiscence points. When does vImage_Buffer.free() truly free reminiscence?

  1. you are in reality a good webmaster The website loading velocity is amazing It sort of feels that youre doing any distinctive trick Also The contents are masterwork you have done a fantastic job in this topic

  2. I loved even more than you will get done right here. The overall look is nice, and the writing is stylish, but there’s something off about the way you write that makes me think that you should be careful what you say next. I will definitely be back again and again if you protect this hike.

Leave a Reply

Your email address will not be published. Required fields are marked *