你的位置:首页 > 操作系统

[操作系统]GPUImage API文档之GPUImageFramebufferCache类


  GPUImageFramebufferCache类负责管理GPUImageFramebuffer对象,是一个GPUImageFramebuffer对象的缓存。

  方法

  - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture

  说明:从cache中获取一个GPUImageFramebuffer对象,如果获取失败,那么创建一个新的GPUImageFramebuffer对象。

  参数:framebufferSize是对象的大小,textureOptions是纹理的配置信息,onlyTexture指示是否只为纹理,是否包含framebuffer对象。

  返回:一个GPUImageFramebuffer对象

  实现

 

- (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;{  __block GPUImageFramebuffer *framebufferFromCache = nil;//  dispatch_sync(framebufferCacheQueue, ^{  runSynchronouslyOnVideoProcessingQueue(^{    NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];    NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash];    NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue];        if ([numberOfMatchingTexturesInCache integerValue] < 1)    {      // Nothing in the cache, create a new framebuffer to use      framebufferFromCache = [[GPUImageFramebuffer alloc] initWithSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];    }    else    {      // Something found, pull the old framebuffer and decrement the count      NSInteger currentTextureID = (numberOfMatchingTextures - 1);      while ((framebufferFromCache == nil) && (currentTextureID >= 0))      {        NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)currentTextureID];        framebufferFromCache = [framebufferCache objectForKey:textureHash];        // Test the values in the cache first, to see if they got invalidated behind our back        if (framebufferFromCache != nil)        {          // Withdraw this from the cache while it's in use          [framebufferCache removeObjectForKey:textureHash];        }        currentTextureID--;      }            currentTextureID++;            [framebufferTypeCounts setObject:[NSNumber numberWithInteger:currentTextureID] forKey:lookupHash];            if (framebufferFromCache == nil)      {        framebufferFromCache = [[GPUImageFramebuffer alloc] initWithSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];      }    }  });  [framebufferFromCache lock];  return framebufferFromCache;}

 

 

 

  - (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize onlyTexture:(BOOL)onlyTexture

  说明:同上

  实现

 

- (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize onlyTexture:(BOOL)onlyTexture;{  GPUTextureOptions defaultTextureOptions;  defaultTextureOptions.minFilter = GL_LINEAR;  defaultTextureOptions.magFilter = GL_LINEAR;  defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;  defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;  defaultTextureOptions.internalFormat = GL_RGBA;  defaultTextureOptions.format = GL_BGRA;  defaultTextureOptions.type = GL_UNSIGNED_BYTE;    return [self fetchFramebufferForSize:framebufferSize textureOptions:defaultTextureOptions onlyTexture:onlyTexture];}

 

  - (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer

  说明:向GPUImageFramebuffer缓存加添加GPUImageFramebuffer对象

  参数:需要添加的GPUImageFramebuffer对象

  实现

 

- (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer;{  [framebuffer clearAllLocks];  //  dispatch_async(framebufferCacheQueue, ^{  runAsynchronouslyOnVideoProcessingQueue(^{    CGSize framebufferSize = framebuffer.size;    GPUTextureOptions framebufferTextureOptions = framebuffer.textureOptions;    NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:framebufferTextureOptions onlyTexture:framebuffer.missingFramebuffer];    NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash];    NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue];        NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)numberOfMatchingTextures];    //    [framebufferCache setObject:framebuffer forKey:textureHash cost:round(framebufferSize.width * framebufferSize.height * 4.0)];    [framebufferCache setObject:framebuffer forKey:textureHash];    [framebufferTypeCounts setObject:[NSNumber numberWithInteger:(numberOfMatchingTextures + 1)] forKey:lookupHash];  });}

 

  - (void)purgeAllUnassignedFramebuffers

  说明:清理缓存中的纹理缓存,清理framebufferCache中的所有对象

  实现

 

- (void)purgeAllUnassignedFramebuffers;{  runAsynchronouslyOnVideoProcessingQueue(^{//  dispatch_async(framebufferCacheQueue, ^{    [framebufferCache removeAllObjects];    [framebufferTypeCounts removeAllObjects];#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    CVOpenGLESTextureCacheFlush([[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], 0);#else#endif  });}

 

 

 

  - (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer

  说明:

  实现

 

- (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;{  runAsynchronouslyOnVideoProcessingQueue(^{//  dispatch_async(framebufferCacheQueue, ^{    [activeImageCaptureList addObject:framebuffer];  });}

 

  - (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer

  说明:

  实现

 

- (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;{  runAsynchronouslyOnVideoProcessingQueue(^{// dispatch_async(framebufferCacheQueue, ^{    [activeImageCaptureList removeObject:framebuffer];  });}

 

 

 

完整代码

#import <Foundation/Foundation.h>#import <QuartzCore/QuartzCore.h>#import "GPUImageFramebuffer.h"@interface GPUImageFramebufferCache : NSObject// Framebuffer management- (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;- (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize onlyTexture:(BOOL)onlyTexture;- (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer;- (void)purgeAllUnassignedFramebuffers;- (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;- (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;@end

 

#import "GPUImageFramebufferCache.h"#import "GPUImageContext.h"#import "GPUImageOutput.h"#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE#import <UIKit/UIKit.h>#else#endif@interface GPUImageFramebufferCache(){//  NSCache *framebufferCache;  NSMutableDictionary *framebufferCache;  NSMutableDictionary *framebufferTypeCounts;  NSMutableArray *activeImageCaptureList; // Where framebuffers that may be lost by a filter, but which are still needed for a UIImage, etc., are stored  id memoryWarningObserver;  dispatch_queue_t framebufferCacheQueue;}- (NSString *)hashForSize:(CGSize)size textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;@end@implementation GPUImageFramebufferCache#pragma mark -#pragma mark Initialization and teardown- (id)init;{  if (!(self = [super init]))  {    return nil;  }  #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE  memoryWarningObserver = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:nil usingBlock:^(NSNotification *note) {        [self purgeAllUnassignedFramebuffers];  }];#else#endif//  framebufferCache = [[NSCache alloc] init];  framebufferCache = [[NSMutableDictionary alloc] init];  framebufferTypeCounts = [[NSMutableDictionary alloc] init];  activeImageCaptureList = [[NSMutableArray alloc] init];  framebufferCacheQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.framebufferCacheQueue", NULL);    return self;}#pragma mark -#pragma mark Framebuffer management- (NSString *)hashForSize:(CGSize)size textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;{  if (onlyTexture)  {    return [NSString stringWithFormat:@"%.1fx%.1f-%d:%d:%d:%d:%d:%d:%d-NOFB", size.width, size.height, textureOptions.minFilter, textureOptions.magFilter, textureOptions.wrapS, textureOptions.wrapT, textureOptions.internalFormat, textureOptions.format, textureOptions.type];  }  else  {    return [NSString stringWithFormat:@"%.1fx%.1f-%d:%d:%d:%d:%d:%d:%d", size.width, size.height, textureOptions.minFilter, textureOptions.magFilter, textureOptions.wrapS, textureOptions.wrapT, textureOptions.internalFormat, textureOptions.format, textureOptions.type];  }}- (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)textureOptions onlyTexture:(BOOL)onlyTexture;{  __block GPUImageFramebuffer *framebufferFromCache = nil;//  dispatch_sync(framebufferCacheQueue, ^{  runSynchronouslyOnVideoProcessingQueue(^{    NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];    NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash];    NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue];        if ([numberOfMatchingTexturesInCache integerValue] < 1)    {      // Nothing in the cache, create a new framebuffer to use      framebufferFromCache = [[GPUImageFramebuffer alloc] initWithSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];    }    else    {      // Something found, pull the old framebuffer and decrement the count      NSInteger currentTextureID = (numberOfMatchingTextures - 1);      while ((framebufferFromCache == nil) && (currentTextureID >= 0))      {        NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)currentTextureID];        framebufferFromCache = [framebufferCache objectForKey:textureHash];        // Test the values in the cache first, to see if they got invalidated behind our back        if (framebufferFromCache != nil)        {          // Withdraw this from the cache while it's in use          [framebufferCache removeObjectForKey:textureHash];        }        currentTextureID--;      }            currentTextureID++;            [framebufferTypeCounts setObject:[NSNumber numberWithInteger:currentTextureID] forKey:lookupHash];            if (framebufferFromCache == nil)      {        framebufferFromCache = [[GPUImageFramebuffer alloc] initWithSize:framebufferSize textureOptions:textureOptions onlyTexture:onlyTexture];      }    }  });  [framebufferFromCache lock];  return framebufferFromCache;}- (GPUImageFramebuffer *)fetchFramebufferForSize:(CGSize)framebufferSize onlyTexture:(BOOL)onlyTexture;{  GPUTextureOptions defaultTextureOptions;  defaultTextureOptions.minFilter = GL_LINEAR;  defaultTextureOptions.magFilter = GL_LINEAR;  defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;  defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;  defaultTextureOptions.internalFormat = GL_RGBA;  defaultTextureOptions.format = GL_BGRA;  defaultTextureOptions.type = GL_UNSIGNED_BYTE;    return [self fetchFramebufferForSize:framebufferSize textureOptions:defaultTextureOptions onlyTexture:onlyTexture];}- (void)returnFramebufferToCache:(GPUImageFramebuffer *)framebuffer;{  [framebuffer clearAllLocks];  //  dispatch_async(framebufferCacheQueue, ^{  runAsynchronouslyOnVideoProcessingQueue(^{    CGSize framebufferSize = framebuffer.size;    GPUTextureOptions framebufferTextureOptions = framebuffer.textureOptions;    NSString *lookupHash = [self hashForSize:framebufferSize textureOptions:framebufferTextureOptions onlyTexture:framebuffer.missingFramebuffer];    NSNumber *numberOfMatchingTexturesInCache = [framebufferTypeCounts objectForKey:lookupHash];    NSInteger numberOfMatchingTextures = [numberOfMatchingTexturesInCache integerValue];        NSString *textureHash = [NSString stringWithFormat:@"%@-%ld", lookupHash, (long)numberOfMatchingTextures];    //    [framebufferCache setObject:framebuffer forKey:textureHash cost:round(framebufferSize.width * framebufferSize.height * 4.0)];    [framebufferCache setObject:framebuffer forKey:textureHash];    [framebufferTypeCounts setObject:[NSNumber numberWithInteger:(numberOfMatchingTextures + 1)] forKey:lookupHash];  });}- (void)purgeAllUnassignedFramebuffers;{  runAsynchronouslyOnVideoProcessingQueue(^{//  dispatch_async(framebufferCacheQueue, ^{    [framebufferCache removeAllObjects];    [framebufferTypeCounts removeAllObjects];#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    CVOpenGLESTextureCacheFlush([[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache], 0);#else#endif  });}- (void)addFramebufferToActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;{  runAsynchronouslyOnVideoProcessingQueue(^{//  dispatch_async(framebufferCacheQueue, ^{    [activeImageCaptureList addObject:framebuffer];  });}- (void)removeFramebufferFromActiveImageCaptureList:(GPUImageFramebuffer *)framebuffer;{  runAsynchronouslyOnVideoProcessingQueue(^{// dispatch_async(framebufferCacheQueue, ^{    [activeImageCaptureList removeObject:framebuffer];  });}@end