Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Releasing an IOSurface

This question is an extension to:
Link-1: Creating an image out of the ios surface and saving it
Link-2: Taking Screenshots from iOS app - emulating Display recorder (query on the internals)

(Refer Link-1) I have the code for taking screenshots in the background working. But as stated, it requires a sleep of 2 sec to work uninterruptedly, otherwise the OS suspends the app. I figured out the reason could be that I am not explicitly releasing the IOSurface I create.
Reason - Using the link http://pastie.org/pastes/3734430 given by Victor Ronin, the capture works fine even without the sleep. I tried releasing the destSurf (destination surface that I have created) using CFRelease after I write the image each time, but that doesn't work.

Any help on when, how and whether or not to release a created IOSurface, will be really useful. Thanks.

Update
So, this is what exactly happens. (Referring Link-1)

IOSurfaceRef destSurf = IOSurfaceCreate(dict);
IOSurfaceAcceleratorRef outAcc;
IOSurfaceAcceleratorCreate(NULL, 0, &outAcc);

CFDictionaryRef ed = (__bridge CFDictionaryRef)[NSDictionary dictionaryWithObjectsAndKeys: nil];
IOSurfaceAcceleratorTransferSurface(outAcc, screenSurface, destSurf, ed, NULL);

IOSurfaceUnlock(screenSurface, kIOSurfaceLockReadOnly, &aseed);

CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, IOSurfaceGetBaseAddress(destSurf), (width*height*4), NULL);
CGImageRef cgImage=CGImageCreate(width, height, 8, 8*4, IOSurfaceGetBytesPerRow(destSurf), CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, provider, NULL, YES, kCGRenderingIntentDefault);
UIImage *image = [UIImage imageWithCGImage: cgImage];
CGImageRelease(cgImage);
UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);
CFRelease(destSurf);
  1. The call to CFRelease takes place and app crashes. There are no images saved. However, if you put in a sleep of 1-2 sec prior to the release, it works fine.
  2. If you skip the call to UIImageWriteToSavePhotosAlbum(), everything works fine and capture goes without interruption.
    I am still not clear on what exactly is the problem and how to solve it. Any help is highly appreciated.
like image 383
Hrishikesh_Pardeshi Avatar asked Dec 19 '12 12:12

Hrishikesh_Pardeshi


1 Answers

I think you need to release surface. It's create by API IOSurfaceCreate which isn't managed by autorelease's.

As example I found following code where it's released:

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=8&cad=rja&ved=0CF0QFjAH&url=http%3A%2F%2Fcode.google.com%2Fp%2Fsyphon-framework%2Fsource%2Fbrowse%2Ftags%2Fpublic-beta-1%2FSyphonServer.m%3Fr%3D3&ei=i_zRUMWQDMqw0AHs7IHYDA&usg=AFQjCNG9yO3sUf-ZQy-W_h_Q9WJMm4hqgw

http://www.opensource.apple.com/source/WebCore/WebCore-7536.24/platform/graphics/surfaces/mac/GraphicsSurfaceMac.cpp?txt

What happens if you try to release it with CFRelease? Does it crash or does it have the same 2 secs problem?

like image 64
Victor Ronin Avatar answered Sep 21 '22 19:09

Victor Ronin