@@ -7,6 +7,7 @@ @interface GPUImageFramebuffer()
7
7
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
8
8
CVPixelBufferRef renderTarget;
9
9
CVOpenGLESTextureRef renderTexture;
10
+ NSUInteger readLockCount;
10
11
#else
11
12
#endif
12
13
NSUInteger framebufferReferenceCount;
@@ -330,7 +331,7 @@ - (CGImageRef)newCGImageFromFramebufferContents;
330
331
331
332
glFinish ();
332
333
CFRetain (renderTarget); // I need to retain the pixel buffer here and release in the data source callback to prevent its bytes from being prematurely deallocated during a photo write operation
333
- CVPixelBufferLockBaseAddress (renderTarget, 0 ) ;
334
+ [ self lockForReading ] ;
334
335
rawImagePixels = (GLubyte *)CVPixelBufferGetBaseAddress (renderTarget);
335
336
dataProvider = CGDataProviderCreateWithData ((__bridge_retained void *)self, rawImagePixels, paddedBytesForImage, dataProviderUnlockCallback);
336
337
[[GPUImageContext sharedFramebufferCache ] addFramebufferToActiveImageCaptureList: self ]; // In case the framebuffer is swapped out on the filter, need to have a strong reference to it somewhere for it to hang on while the image is in existence
@@ -372,7 +373,7 @@ - (CGImageRef)newCGImageFromFramebufferContents;
372
373
- (void )restoreRenderTarget ;
373
374
{
374
375
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
375
- CVPixelBufferUnlockBaseAddress (renderTarget, 0 ) ;
376
+ [ self unlockAfterReading ] ;
376
377
CFRelease (renderTarget);
377
378
#else
378
379
#endif
@@ -381,6 +382,35 @@ - (void)restoreRenderTarget;
381
382
#pragma mark -
382
383
#pragma mark Raw data bytes
383
384
385
+ - (void )lockForReading
386
+ {
387
+ #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
388
+ if ([GPUImageContext supportsFastTextureUpload ])
389
+ {
390
+ if (readLockCount == 0 )
391
+ {
392
+ CVPixelBufferLockBaseAddress (renderTarget, 0 );
393
+ }
394
+ readLockCount++;
395
+ }
396
+ #endif
397
+ }
398
+
399
+ - (void )unlockAfterReading
400
+ {
401
+ #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
402
+ if ([GPUImageContext supportsFastTextureUpload ])
403
+ {
404
+ NSAssert (readLockCount > 0 , @" Unbalanced call to -[GPUImageFramebuffer unlockAfterReading]" );
405
+ readLockCount--;
406
+ if (readLockCount == 0 )
407
+ {
408
+ CVPixelBufferUnlockBaseAddress (renderTarget, 0 );
409
+ }
410
+ }
411
+ #endif
412
+ }
413
+
384
414
- (NSUInteger )bytesPerRow ;
385
415
{
386
416
if ([GPUImageContext supportsFastTextureUpload ])
@@ -400,9 +430,9 @@ - (NSUInteger)bytesPerRow;
400
430
- (GLubyte *)byteBuffer ;
401
431
{
402
432
#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE
403
- CVPixelBufferLockBaseAddress (renderTarget, 0 ) ;
433
+ [ self lockForReading ] ;
404
434
GLubyte * bufferBytes = CVPixelBufferGetBaseAddress (renderTarget);
405
- CVPixelBufferUnlockBaseAddress (renderTarget, 0 ) ;
435
+ [ self unlockAfterReading ] ;
406
436
return bufferBytes;
407
437
#else
408
438
return NULL ; // TODO: do more with this on the non-texture-cache side
0 commit comments