0

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

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

4

3 回答 3

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 方法,在大多数情况下都会遇到问题。

于 2012-08-07T08:47:18.377 回答
0

这对我来说看起来不错,假设uiImage,和同时没有被另一个线程操作。(假设您使用的是 iOS 4 及更高版本。)_width_height_data

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

于 2012-08-06T18:43:23.800 回答
0

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

于 2012-08-06T18:48:43.377 回答