2012-08-06 4 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); 

동일한 결과를 얻으려면 어떻게해야합니까?

답변

1

이 코드를 GL의 별도 스레드에서 실행하면 문제가 발생할 수 있습니다. 효과가 있다고하더라도 이미지/텍스처의 절반을 그릴 수 있습니다. 이중 버퍼를 작성하면이 문제를 피할 수 있습니다. "_ 데이터"는 한 번만 할당되어야하며 2 개의 원시 이미지 데이터 버퍼를 보유해야합니다. 그런 다음 전경 및 배경 버퍼로 정의 된 2 개의 포인터를 작성하십시오 (void * fg = _data [0], void * bg = _data [1]). 이제 당신의 메서드가 CGImage에서 bg로 데이터를 수집 할 때 단지 포인터를 바꾼다. (void * fg = _data [1], void * bg = _data [0] 또는 그 반대로) GL 스레드는 텍스처로 데이터를 채워야한다. on fg (그림과 같은 스레드).

또한 일부 잠금 메커니즘을해야 할 수도 있습니다

  1. 을 당신이 '버퍼 스왑 "푸시 후 잠금 해제를 고정해야 텍스처 데이터를 푸시하기 전에.

  2. 버퍼가 스왑 된 것인지 알고 싶을 경우 fg 데이터를 경우에만 텍스처로 푸시하면됩니다.

더 많은 스레드에서 GL 메소드를 호출하면 대부분의 경우 문제가 발생합니다.

+0

나는이 대답을 좋아하지만 완전히 이해할 수는 없다. – Geri

+0

잠시 동안 버퍼를 "유지"하는 것과 같은 것입니까? 텍스처에 이미지를 푸시 할 때마다 UIImageDataParser 인스턴스를 생성하므로 버퍼가 "혼합"해서는 안됩니다. 어쩌면 버퍼를 일찍 풀어 줄 수 있을까요? – Geri

+0

백그라운드 스레드에서 데이터 개체를 릴리스하려고 시도했지만 결과가 없습니다. – Geri

0

는 가정, 나에게 확인을 보이는 (내 문제는 백그라운드에서 실행되는 경우 나,이 방법의 출력 버퍼를 기반으로 내 OpenGL은 텍스처를 볼 수 있다는 것입니다) uiImage, _width, _height_data은 다른 스레드에서 동시에 조작되지 않습니다. (iOS 4 이상을 사용한다고 가정하십시오.)

배경 스레드에 텍스처를 OpenGL에 업로드하고 있습니까? 그렇다면, 아마도 문제 일 것입니다. 주어진 OpenGL 컨텍스트는 한 번에 하나의 스레드에서만 액세스해야하기 때문입니다.

0

UIKit (또는 유사한 프레임 워크) (직접 또는 간접적으로)에 액세스하지 않는 한 여러 스레드에서 코드의 변수에 액세스하지 않는 한 괜찮습니다.

관련 문제