2012-08-06 147 views
0

或者这个代码可以安全地在后台线程中执行?此UIImage数据读取器线程安全吗?

CGImageRef cgImage; 
    CGContextRef context; 
    CGColorSpaceRef colorSpace; 

    // Sets the CoreGraphic Image to work on it. 
    cgImage = [uiImage CGImage]; 

    // Sets the image's size. 
    _width = CGImageGetWidth(cgImage); 
    _height = CGImageGetHeight(cgImage); 

    // Extracts the pixel informations and place it into the data. 
    colorSpace = CGColorSpaceCreateDeviceRGB(); 
    _data = malloc(_width * _height * 4); 
    context = CGBitmapContextCreate(_data, _width, _height, 8, 4 * _width, colorSpace, 
            kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 
    CGColorSpaceRelease(colorSpace); 

    // Adjusts position and invert the image. 
    // The OpenGL uses the image data upside-down compared commom image files. 
    CGContextTranslateCTM(context, 0, _height); 
    CGContextScaleCTM(context, 1.0, -1.0); 

    // Clears and ReDraw the image into the context. 
    CGContextClearRect(context, CGRectMake(0, 0, _width, _height)); 
    CGContextDrawImage(context, CGRectMake(0, 0, _width, _height), cgImage); 

    // Releases the context. 
    CGContextRelease(context); 

如果获得相同的结果,如果没有?

(我的问题是,我不能看到我的OpenGL纹理基于该方法的输出缓冲,如果它在后台运行)

回答

1

我想你可能会遇到这样的问题,在GL的独立线程上运行这样的代码。即使它可以工作,你可能会遇到半绘制的图像/纹理。您可以通过创建一个双缓冲区来避免这种情况: 您的“_data”应该只分配一次,并应该保存2个原始图像数据缓冲区。然后,只需创建2个定义为前景和背景缓冲区的指针(void * fg = _data [0],void * bg = _data [1]开头)。现在当你的方法从CGImage向bg收集数据时,只需交换指针(然后void * fg = _data [1],void * bg = _data [0]或其他方式) 现在,GL线程应该用数据填充纹理在fg上(与图纸相同的线程)。您将数据推送到纹理时,应该锁定“缓冲交换”和推后 解锁之前

  1. 你也可能需要一些锁定机制。

  2. 您可能会想知道 缓冲区是否已被交换,并且仅在此类 的情况下将fg数据推送到纹理。

另请注意,如果您在多于1个线程上调用GL方法,则在大多数情况下会遇到问题。

+0

我喜欢这个答案,但我完全无法理解它。 – Geri 2012-08-07 11:15:19

+0

这是否像“保留”缓冲区一段时间?每次我想将图像推送到纹理时,我都会创建一个UIImageDataParser实例,所以缓冲区不应该“混淆”。也许我只是简单地释放缓冲区? – Geri 2012-08-07 11:17:16

+0

我试图在后台线程上释放数据对象,但没有结果。 – Geri 2012-08-07 11:22:51

0

这看起来好对我来说,假设uiImage_width_height_data没有被同时从另一个线程操作。 (假设你使用的是iOS 4及以上)。

你是否在后台线程上传纹理到OpenGL?如果是这样,这可能是问题(因为给定的OpenGL上下文应该只能从一个线程一次访问)。

0

只要你不直接或间接地访问UIKit(或类似的框架),并且只要你不从多个线程访问代码中的变量,就没关系。