2012-08-06 189 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(或類似的框架),並且只要你不從多個線程訪問代碼中的變量,就沒關係。