或者这段代码可以安全地在后台线程中执行吗?
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纹理)
答案 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上的数据填充你的纹理(与绘图相同的线程)。
您可能还需要一些锁定机制:
在将数据推送到纹理之前,您应该锁定“缓冲区交换”和 推后解锁。
你可能想知道是否 缓冲区已被交换,并且只将fg数据推送到纹理中 情况下。
另请注意,如果您在多于1个线程上调用GL方法,则在大多数情况下会遇到问题。
答案 1 :(得分:0)
对我来说这似乎没关系,假设uiImage
,_width
,_height
和_data
没有同时从另一个线程进行操作。 (假设您使用的是iOS 4及更高版本。)
您是否在后台线程上将纹理上传到OpenGL?如果是这样,那可能就是问题(因为给定的OpenGL上下文一次只能从一个线程访问)。
答案 2 :(得分:0)
只要您不访问UIKit(或类似框架)(直接或间接),并且只要您不从多个线程访问代码中的变量,就可以了。