这个UIImage数据读取器线程安全吗?

时间:2012-08-06 18:38:58

标签: ios opengl-es uiimage thread-safety

或者这段代码可以安全地在后台线程中执行吗?

    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纹理)

3 个答案:

答案 0 :(得分: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数据推送到纹理中     情况下。

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

答案 1 :(得分:0)

对我来说这似乎没关系,假设uiImage_width_height_data没有同时从另一个线程进行操作。 (假设您使用的是iOS 4及更高版本。)

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

答案 2 :(得分:0)

只要您不访问UIKit(或类似框架)(直接或间接),并且只要您不从多个线程访问代码中的变量,就可以了。